mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 20:27:58 +00:00
Run cargo fmt on the whole code base (#9394)
* Run cargo fmt on the whole code base * Second run * Add CI check * Fix compilation * More unnecessary braces * Handle weights * Use --all * Use correct attributes... * Fix UI tests * AHHHHHHHHH * 🤦 * Docs * Fix compilation * 🤷 * Please stop * 🤦 x 2 * More * make rustfmt.toml consistent with polkadot Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
@@ -26,8 +26,10 @@
|
||||
//! 3. The [`PassByEnum`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Enum`.
|
||||
//! 4. The [`PassByInner`](derive.PassByInner.html) derive macro for implementing `PassBy` with `Inner`.
|
||||
|
||||
use syn::{parse_macro_input, ItemTrait, DeriveInput, Result, Token};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::{
|
||||
parse::{Parse, ParseStream},
|
||||
parse_macro_input, DeriveInput, ItemTrait, Result, Token,
|
||||
};
|
||||
|
||||
mod pass_by;
|
||||
mod runtime_interface;
|
||||
@@ -35,7 +37,7 @@ mod utils;
|
||||
|
||||
struct Options {
|
||||
wasm_only: bool,
|
||||
tracing: bool
|
||||
tracing: bool,
|
||||
}
|
||||
|
||||
impl Options {
|
||||
@@ -86,17 +88,21 @@ pub fn runtime_interface(
|
||||
#[proc_macro_derive(PassByCodec)]
|
||||
pub fn pass_by_codec(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
pass_by::codec_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
pass_by::codec_derive_impl(input)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(PassByInner)]
|
||||
pub fn pass_by_inner(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
pass_by::inner_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
pass_by::inner_derive_impl(input)
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
#[proc_macro_derive(PassByEnum)]
|
||||
pub fn pass_by_enum(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
pass_by::enum_derive_impl(input).unwrap_or_else(|e| e.to_compile_error()).into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
|
||||
|
||||
use syn::{DeriveInput, Result, Generics, parse_quote};
|
||||
use syn::{parse_quote, DeriveInput, Generics, Result};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
@@ -53,7 +53,7 @@ pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
|
||||
fn add_trait_bounds(generics: &mut Generics) {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
generics.type_params_mut()
|
||||
generics
|
||||
.type_params_mut()
|
||||
.for_each(|type_param| type_param.bounds.push(parse_quote!(#crate_::codec::Codec)));
|
||||
}
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
|
||||
|
||||
use syn::{DeriveInput, Result, Data, Fields, Error, Ident};
|
||||
use syn::{Data, DeriveInput, Error, Fields, Ident, Result};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
/// The derive implementation for `PassBy` with `Enum`.
|
||||
pub fn derive_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||
@@ -81,22 +81,21 @@ pub fn derive_impl(input: DeriveInput) -> Result<TokenStream> {
|
||||
/// enum or a variant is not an unit.
|
||||
fn get_enum_field_idents<'a>(data: &'a Data) -> Result<impl Iterator<Item = Result<&'a Ident>>> {
|
||||
match data {
|
||||
Data::Enum(d) => {
|
||||
Data::Enum(d) =>
|
||||
if d.variants.len() <= 256 {
|
||||
Ok(
|
||||
d.variants.iter().map(|v| if let Fields::Unit = v.fields {
|
||||
Ok(d.variants.iter().map(|v| {
|
||||
if let Fields::Unit = v.fields {
|
||||
Ok(&v.ident)
|
||||
} else {
|
||||
Err(Error::new(
|
||||
Span::call_site(),
|
||||
"`PassByEnum` only supports unit variants.",
|
||||
))
|
||||
})
|
||||
)
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
Err(Error::new(Span::call_site(), "`PassByEnum` only supports `256` variants."))
|
||||
}
|
||||
},
|
||||
_ => Err(Error::new(Span::call_site(), "`PassByEnum` only supports enums as input type."))
|
||||
},
|
||||
_ => Err(Error::new(Span::call_site(), "`PassByEnum` only supports enums as input type.")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
use crate::utils::{generate_crate_access, generate_runtime_interface_include};
|
||||
|
||||
use syn::{DeriveInput, Result, Generics, parse_quote, Type, Data, Error, Fields, Ident};
|
||||
use syn::{parse_quote, Data, DeriveInput, Error, Fields, Generics, Ident, Result, Type};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
/// The derive implementation for `PassBy` with `Inner` and `PassByInner`.
|
||||
pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
|
||||
@@ -80,7 +80,8 @@ pub fn derive_impl(mut input: DeriveInput) -> Result<TokenStream> {
|
||||
fn add_trait_bounds(generics: &mut Generics) {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
generics.type_params_mut()
|
||||
generics
|
||||
.type_params_mut()
|
||||
.for_each(|type_param| type_param.bounds.push(parse_quote!(#crate_::RIType)));
|
||||
}
|
||||
|
||||
@@ -97,15 +98,13 @@ fn extract_inner_ty_and_name(data: &Data) -> Result<(Type, Option<Ident>)> {
|
||||
Fields::Unnamed(ref unnamed) if unnamed.unnamed.len() == 1 => {
|
||||
let field = &unnamed.unnamed[0];
|
||||
return Ok((field.ty.clone(), field.ident.clone()))
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
Err(
|
||||
Error::new(
|
||||
Span::call_site(),
|
||||
"Only newtype/one field structs are supported by `PassByInner`!",
|
||||
)
|
||||
)
|
||||
Err(Error::new(
|
||||
Span::call_site(),
|
||||
"Only newtype/one field structs are supported by `PassByInner`!",
|
||||
))
|
||||
}
|
||||
|
||||
+49
-61
@@ -30,15 +30,16 @@
|
||||
//! are feature-gated, so that one is compiled for the native and the other for the wasm side.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, create_exchangeable_host_function_ident, get_function_arguments,
|
||||
get_function_argument_names, get_runtime_interface, create_function_ident_with_version,
|
||||
create_exchangeable_host_function_ident, create_function_ident_with_version,
|
||||
generate_crate_access, get_function_argument_names, get_function_arguments,
|
||||
get_runtime_interface,
|
||||
};
|
||||
|
||||
use syn::{
|
||||
Ident, ItemTrait, TraitItemMethod, FnArg, Signature, Result, spanned::Spanned, parse_quote,
|
||||
parse_quote, spanned::Spanned, FnArg, Ident, ItemTrait, Result, Signature, TraitItemMethod,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use quote::{quote, quote_spanned};
|
||||
|
||||
@@ -51,21 +52,22 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool, tracing: bool) -> Res
|
||||
let runtime_interface = get_runtime_interface(trait_def)?;
|
||||
|
||||
// latest version dispatch
|
||||
let token_stream: Result<TokenStream> = runtime_interface.latest_versions()
|
||||
.try_fold(
|
||||
TokenStream::new(),
|
||||
|mut t, (latest_version, method)| {
|
||||
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
|
||||
Ok(t)
|
||||
}
|
||||
);
|
||||
let token_stream: Result<TokenStream> = runtime_interface.latest_versions().try_fold(
|
||||
TokenStream::new(),
|
||||
|mut t, (latest_version, method)| {
|
||||
t.extend(function_for_method(method, latest_version, is_wasm_only)?);
|
||||
Ok(t)
|
||||
},
|
||||
);
|
||||
|
||||
// earlier versions compatibility dispatch (only std variant)
|
||||
let result: Result<TokenStream> = runtime_interface.all_versions().try_fold(token_stream?, |mut t, (version, method)|
|
||||
{
|
||||
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
|
||||
Ok(t)
|
||||
});
|
||||
let result: Result<TokenStream> =
|
||||
runtime_interface
|
||||
.all_versions()
|
||||
.try_fold(token_stream?, |mut t, (version, method)| {
|
||||
t.extend(function_std_impl(trait_name, method, version, is_wasm_only, tracing)?);
|
||||
Ok(t)
|
||||
});
|
||||
|
||||
result
|
||||
}
|
||||
@@ -76,21 +78,16 @@ fn function_for_method(
|
||||
latest_version: u32,
|
||||
is_wasm_only: bool,
|
||||
) -> Result<TokenStream> {
|
||||
let std_impl = if !is_wasm_only {
|
||||
function_std_latest_impl(method, latest_version)?
|
||||
} else {
|
||||
quote!()
|
||||
};
|
||||
let std_impl =
|
||||
if !is_wasm_only { function_std_latest_impl(method, latest_version)? } else { quote!() };
|
||||
|
||||
let no_std_impl = function_no_std_impl(method)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#std_impl
|
||||
Ok(quote! {
|
||||
#std_impl
|
||||
|
||||
#no_std_impl
|
||||
}
|
||||
)
|
||||
#no_std_impl
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates the bare function implementation for `cfg(not(feature = "std"))`.
|
||||
@@ -102,31 +99,27 @@ fn function_no_std_impl(method: &TraitItemMethod) -> Result<TokenStream> {
|
||||
let return_value = &method.sig.output;
|
||||
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#( #attrs )*
|
||||
pub fn #function_name( #( #args, )* ) #return_value {
|
||||
// Call the host function
|
||||
#host_function_name.get()( #( #arg_names, )* )
|
||||
}
|
||||
Ok(quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#( #attrs )*
|
||||
pub fn #function_name( #( #args, )* ) #return_value {
|
||||
// Call the host function
|
||||
#host_function_name.get()( #( #arg_names, )* )
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate call to latest function version for `cfg((feature = "std")`
|
||||
///
|
||||
/// This should generate simple `fn func(..) { func_version_<latest_version>(..) }`.
|
||||
fn function_std_latest_impl(
|
||||
method: &TraitItemMethod,
|
||||
latest_version: u32,
|
||||
) -> Result<TokenStream> {
|
||||
fn function_std_latest_impl(method: &TraitItemMethod, latest_version: u32) -> Result<TokenStream> {
|
||||
let function_name = &method.sig.ident;
|
||||
let args = get_function_arguments(&method.sig).map(FnArg::Typed);
|
||||
let arg_names = get_function_argument_names(&method.sig).collect::<Vec<_>>();
|
||||
let return_value = &method.sig.output;
|
||||
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
|
||||
let latest_function_name = create_function_ident_with_version(&method.sig.ident, latest_version);
|
||||
let latest_function_name =
|
||||
create_function_ident_with_version(&method.sig.ident, latest_version);
|
||||
|
||||
Ok(quote_spanned! { method.span() =>
|
||||
#[cfg(feature = "std")]
|
||||
@@ -153,17 +146,16 @@ fn function_std_impl(
|
||||
let crate_ = generate_crate_access();
|
||||
let args = get_function_arguments(&method.sig).map(FnArg::Typed).chain(
|
||||
// Add the function context as last parameter when this is a wasm only interface.
|
||||
iter::from_fn(||
|
||||
iter::from_fn(|| {
|
||||
if is_wasm_only {
|
||||
Some(
|
||||
parse_quote!(
|
||||
mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext
|
||||
)
|
||||
)
|
||||
Some(parse_quote!(
|
||||
mut __function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
).take(1),
|
||||
})
|
||||
.take(1),
|
||||
);
|
||||
let return_value = &method.sig.output;
|
||||
let attrs = method.attrs.iter().filter(|a| !a.path.is_ident("version"));
|
||||
@@ -179,15 +171,13 @@ fn function_std_impl(
|
||||
)
|
||||
};
|
||||
|
||||
Ok(
|
||||
quote_spanned! { method.span() =>
|
||||
#[cfg(feature = "std")]
|
||||
#( #attrs )*
|
||||
fn #function_name( #( #args, )* ) #return_value {
|
||||
#call_to_trait
|
||||
}
|
||||
Ok(quote_spanned! { method.span() =>
|
||||
#[cfg(feature = "std")]
|
||||
#( #attrs )*
|
||||
fn #function_name( #( #args, )* ) #return_value {
|
||||
#call_to_trait
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the call to the interface trait.
|
||||
@@ -199,10 +189,8 @@ fn generate_call_to_trait(
|
||||
) -> TokenStream {
|
||||
let crate_ = generate_crate_access();
|
||||
let method_name = create_function_ident_with_version(&method.sig.ident, version);
|
||||
let expect_msg = format!(
|
||||
"`{}` called outside of an Externalities-provided environment.",
|
||||
method_name,
|
||||
);
|
||||
let expect_msg =
|
||||
format!("`{}` called outside of an Externalities-provided environment.", method_name,);
|
||||
let arg_names = get_function_argument_names(&method.sig);
|
||||
|
||||
if takes_self_argument(&method.sig) {
|
||||
|
||||
+157
-171
@@ -22,35 +22,36 @@
|
||||
//! executor. These implementations call the bare function interface.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access, create_host_function_ident, get_function_argument_names,
|
||||
get_function_argument_types_without_ref, get_function_argument_types_ref_and_mut,
|
||||
get_function_argument_names_and_types_without_ref, get_function_arguments,
|
||||
get_function_argument_types, create_exchangeable_host_function_ident, get_runtime_interface,
|
||||
create_function_ident_with_version,
|
||||
create_exchangeable_host_function_ident, create_function_ident_with_version,
|
||||
create_host_function_ident, generate_crate_access, get_function_argument_names,
|
||||
get_function_argument_names_and_types_without_ref, get_function_argument_types,
|
||||
get_function_argument_types_ref_and_mut, get_function_argument_types_without_ref,
|
||||
get_function_arguments, get_runtime_interface,
|
||||
};
|
||||
|
||||
use syn::{
|
||||
ItemTrait, TraitItemMethod, Result, ReturnType, Ident, Pat, Error, Signature, spanned::Spanned,
|
||||
spanned::Spanned, Error, Ident, ItemTrait, Pat, Result, ReturnType, Signature, TraitItemMethod,
|
||||
};
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use quote::{quote, ToTokens};
|
||||
|
||||
use inflector::Inflector;
|
||||
|
||||
use std::iter::{Iterator, self};
|
||||
use std::iter::{self, Iterator};
|
||||
|
||||
/// Generate the extern host functions for wasm and the `HostFunctions` struct that provides the
|
||||
/// implementations for the host functions on the host.
|
||||
pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
|
||||
let trait_name = &trait_def.ident;
|
||||
let extern_host_function_impls = get_runtime_interface(trait_def)?
|
||||
.latest_versions()
|
||||
.try_fold(TokenStream::new(), |mut t, (version, method)| {
|
||||
let extern_host_function_impls = get_runtime_interface(trait_def)?.latest_versions().try_fold(
|
||||
TokenStream::new(),
|
||||
|mut t, (version, method)| {
|
||||
t.extend(generate_extern_host_function(method, version, trait_name)?);
|
||||
Ok::<_, Error>(t)
|
||||
})?;
|
||||
},
|
||||
)?;
|
||||
let exchangeable_host_functions = get_runtime_interface(trait_def)?
|
||||
.latest_versions()
|
||||
.try_fold(TokenStream::new(), |mut t, (_, m)| {
|
||||
@@ -59,27 +60,29 @@ pub fn generate(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream
|
||||
})?;
|
||||
let host_functions_struct = generate_host_functions_struct(trait_def, is_wasm_only)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
/// The implementations of the extern host functions. This special implementation module
|
||||
/// is required to change the extern host functions signature to
|
||||
/// `unsafe fn name(args) -> ret` to make the function implementations exchangeable.
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod extern_host_function_impls {
|
||||
use super::*;
|
||||
Ok(quote! {
|
||||
/// The implementations of the extern host functions. This special implementation module
|
||||
/// is required to change the extern host functions signature to
|
||||
/// `unsafe fn name(args) -> ret` to make the function implementations exchangeable.
|
||||
#[cfg(not(feature = "std"))]
|
||||
mod extern_host_function_impls {
|
||||
use super::*;
|
||||
|
||||
#extern_host_function_impls
|
||||
}
|
||||
|
||||
#exchangeable_host_functions
|
||||
|
||||
#host_functions_struct
|
||||
#extern_host_function_impls
|
||||
}
|
||||
)
|
||||
|
||||
#exchangeable_host_functions
|
||||
|
||||
#host_functions_struct
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the extern host function for the given method.
|
||||
fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_name: &Ident) -> Result<TokenStream> {
|
||||
fn generate_extern_host_function(
|
||||
method: &TraitItemMethod,
|
||||
version: u32,
|
||||
trait_name: &Ident,
|
||||
) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
let args = get_function_arguments(&method.sig);
|
||||
let arg_types = get_function_argument_types_without_ref(&method.sig);
|
||||
@@ -106,33 +109,31 @@ fn generate_extern_host_function(method: &TraitItemMethod, version: u32, trait_n
|
||||
ReturnType::Default => quote!(),
|
||||
ReturnType::Type(_, ref ty) => quote! {
|
||||
<#ty as #crate_::wasm::FromFFIValue>::from_ffi_value(result)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[doc = #doc_string]
|
||||
pub fn #function ( #( #args ),* ) #return_value {
|
||||
extern "C" {
|
||||
/// The extern function.
|
||||
pub fn #ext_function (
|
||||
#( #arg_names: <#arg_types as #crate_::RIType>::FFIType ),*
|
||||
) #ffi_return_value;
|
||||
}
|
||||
|
||||
// Generate all wrapped ffi values.
|
||||
#(
|
||||
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
|
||||
&#arg_names2,
|
||||
);
|
||||
)*
|
||||
|
||||
let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
|
||||
|
||||
#convert_return_value
|
||||
Ok(quote! {
|
||||
#[doc = #doc_string]
|
||||
pub fn #function ( #( #args ),* ) #return_value {
|
||||
extern "C" {
|
||||
/// The extern function.
|
||||
pub fn #ext_function (
|
||||
#( #arg_names: <#arg_types as #crate_::RIType>::FFIType ),*
|
||||
) #ffi_return_value;
|
||||
}
|
||||
|
||||
// Generate all wrapped ffi values.
|
||||
#(
|
||||
let #arg_names2 = <#arg_types2 as #crate_::wasm::IntoFFIValue>::into_ffi_value(
|
||||
&#arg_names2,
|
||||
);
|
||||
)*
|
||||
|
||||
let result = unsafe { #ext_function( #( #arg_names3.get() ),* ) };
|
||||
|
||||
#convert_return_value
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the host exchangeable function for the given method.
|
||||
@@ -144,44 +145,43 @@ fn generate_exchangeable_host_function(method: &TraitItemMethod) -> Result<Token
|
||||
let doc_string = format!(" Exchangeable host function used by [`{}`].", method.sig.ident);
|
||||
let output = &method.sig.output;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[doc = #doc_string]
|
||||
pub static #exchangeable_function : #crate_::wasm::ExchangeableFunction<
|
||||
fn ( #( #arg_types ),* ) #output
|
||||
> = #crate_::wasm::ExchangeableFunction::new(extern_host_function_impls::#function);
|
||||
}
|
||||
)
|
||||
Ok(quote! {
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[doc = #doc_string]
|
||||
pub static #exchangeable_function : #crate_::wasm::ExchangeableFunction<
|
||||
fn ( #( #arg_types ),* ) #output
|
||||
> = #crate_::wasm::ExchangeableFunction::new(extern_host_function_impls::#function);
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the `HostFunctions` struct that implements `wasm-interface::HostFunctions` to provide
|
||||
/// implementations for the extern host functions.
|
||||
fn generate_host_functions_struct(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream> {
|
||||
fn generate_host_functions_struct(
|
||||
trait_def: &ItemTrait,
|
||||
is_wasm_only: bool,
|
||||
) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
let host_functions = get_runtime_interface(trait_def)?
|
||||
.all_versions()
|
||||
.map(|(version, method)|
|
||||
.map(|(version, method)| {
|
||||
generate_host_function_implementation(&trait_def.ident, method, version, is_wasm_only)
|
||||
)
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
/// Provides implementations for the extern host functions.
|
||||
#[cfg(feature = "std")]
|
||||
pub struct HostFunctions;
|
||||
Ok(quote! {
|
||||
/// Provides implementations for the extern host functions.
|
||||
#[cfg(feature = "std")]
|
||||
pub struct HostFunctions;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions {
|
||||
fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> {
|
||||
vec![ #( #host_functions ),* ]
|
||||
}
|
||||
#[cfg(feature = "std")]
|
||||
impl #crate_::sp_wasm_interface::HostFunctions for HostFunctions {
|
||||
fn host_functions() -> Vec<&'static dyn #crate_::sp_wasm_interface::Function> {
|
||||
vec![ #( #host_functions ),* ]
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generates the host function struct that implements `wasm_interface::Function` and returns a static
|
||||
@@ -199,71 +199,65 @@ fn generate_host_function_implementation(
|
||||
let struct_name = Ident::new(&name.to_pascal_case(), Span::call_site());
|
||||
let crate_ = generate_crate_access();
|
||||
let signature = generate_wasm_interface_signature_for_host_function(&method.sig)?;
|
||||
let wasm_to_ffi_values = generate_wasm_to_ffi_values(
|
||||
&method.sig,
|
||||
trait_name,
|
||||
).collect::<Result<Vec<_>>>()?;
|
||||
let wasm_to_ffi_values =
|
||||
generate_wasm_to_ffi_values(&method.sig, trait_name).collect::<Result<Vec<_>>>()?;
|
||||
let ffi_to_host_values = generate_ffi_to_host_value(&method.sig).collect::<Result<Vec<_>>>()?;
|
||||
let host_function_call = generate_host_function_call(&method.sig, version, is_wasm_only);
|
||||
let into_preallocated_ffi_value = generate_into_preallocated_ffi_value(&method.sig)?;
|
||||
let convert_return_value = generate_return_value_into_wasm_value(&method.sig);
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
{
|
||||
struct #struct_name;
|
||||
Ok(quote! {
|
||||
{
|
||||
struct #struct_name;
|
||||
|
||||
impl #crate_::sp_wasm_interface::Function for #struct_name {
|
||||
fn name(&self) -> &str {
|
||||
#name
|
||||
}
|
||||
|
||||
fn signature(&self) -> #crate_::sp_wasm_interface::Signature {
|
||||
#signature
|
||||
}
|
||||
|
||||
fn execute(
|
||||
&self,
|
||||
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
|
||||
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
|
||||
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
|
||||
#( #wasm_to_ffi_values )*
|
||||
#( #ffi_to_host_values )*
|
||||
#host_function_call
|
||||
#into_preallocated_ffi_value
|
||||
#convert_return_value
|
||||
}
|
||||
impl #crate_::sp_wasm_interface::Function for #struct_name {
|
||||
fn name(&self) -> &str {
|
||||
#name
|
||||
}
|
||||
|
||||
&#struct_name as &dyn #crate_::sp_wasm_interface::Function
|
||||
fn signature(&self) -> #crate_::sp_wasm_interface::Signature {
|
||||
#signature
|
||||
}
|
||||
|
||||
fn execute(
|
||||
&self,
|
||||
__function_context__: &mut dyn #crate_::sp_wasm_interface::FunctionContext,
|
||||
args: &mut dyn Iterator<Item = #crate_::sp_wasm_interface::Value>,
|
||||
) -> std::result::Result<Option<#crate_::sp_wasm_interface::Value>, String> {
|
||||
#( #wasm_to_ffi_values )*
|
||||
#( #ffi_to_host_values )*
|
||||
#host_function_call
|
||||
#into_preallocated_ffi_value
|
||||
#convert_return_value
|
||||
}
|
||||
}
|
||||
|
||||
&#struct_name as &dyn #crate_::sp_wasm_interface::Function
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the `wasm_interface::Signature` for the given host function `sig`.
|
||||
fn generate_wasm_interface_signature_for_host_function(sig: &Signature) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
let return_value = match &sig.output {
|
||||
ReturnType::Type(_, ty) =>
|
||||
quote! {
|
||||
Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE )
|
||||
},
|
||||
ReturnType::Default => quote!( None ),
|
||||
ReturnType::Type(_, ty) => quote! {
|
||||
Some( <<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE )
|
||||
},
|
||||
ReturnType::Default => quote!(None),
|
||||
};
|
||||
let arg_types = get_function_argument_types_without_ref(sig)
|
||||
.map(|ty| quote! {
|
||||
<<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE
|
||||
});
|
||||
|
||||
Ok(
|
||||
let arg_types = get_function_argument_types_without_ref(sig).map(|ty| {
|
||||
quote! {
|
||||
#crate_::sp_wasm_interface::Signature {
|
||||
args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]),
|
||||
return_value: #return_value,
|
||||
}
|
||||
<<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::IntoValue>::VALUE_TYPE
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
Ok(quote! {
|
||||
#crate_::sp_wasm_interface::Signature {
|
||||
args: std::borrow::Cow::Borrowed(&[ #( #arg_types ),* ][..]),
|
||||
return_value: #return_value,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the code that converts the wasm values given to `HostFunctions::execute` into the FFI
|
||||
@@ -279,24 +273,23 @@ fn generate_wasm_to_ffi_values<'a>(
|
||||
function_name,
|
||||
);
|
||||
|
||||
get_function_argument_names_and_types_without_ref(sig)
|
||||
.map(move |(name, ty)| {
|
||||
let try_from_error = format!(
|
||||
"Could not instantiate `{}` from wasm value while executing `{}` from interface `{}`!",
|
||||
name.to_token_stream(),
|
||||
function_name,
|
||||
trait_name,
|
||||
);
|
||||
get_function_argument_names_and_types_without_ref(sig).map(move |(name, ty)| {
|
||||
let try_from_error = format!(
|
||||
"Could not instantiate `{}` from wasm value while executing `{}` from interface `{}`!",
|
||||
name.to_token_stream(),
|
||||
function_name,
|
||||
trait_name,
|
||||
);
|
||||
|
||||
let var_name = generate_ffi_value_var_name(&name)?;
|
||||
let var_name = generate_ffi_value_var_name(&name)?;
|
||||
|
||||
Ok(quote! {
|
||||
let val = args.next().ok_or_else(|| #error_message)?;
|
||||
let #var_name = <
|
||||
<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue
|
||||
>::try_from_value(val).ok_or_else(|| #try_from_error)?;
|
||||
})
|
||||
Ok(quote! {
|
||||
let val = args.next().ok_or_else(|| #error_message)?;
|
||||
let #var_name = <
|
||||
<#ty as #crate_::RIType>::FFIType as #crate_::sp_wasm_interface::TryFromValue
|
||||
>::try_from_value(val).ok_or_else(|| #try_from_error)?;
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Generate the code to convert the ffi values on the host to the host values using `FromFFIValue`.
|
||||
@@ -311,14 +304,12 @@ fn generate_ffi_to_host_value<'a>(
|
||||
.map(move |((name, ty), mut_access)| {
|
||||
let ffi_value_var_name = generate_ffi_value_var_name(&name)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
let #mut_access #name = <#ty as #crate_::host::FromFFIValue>::from_ffi_value(
|
||||
__function_context__,
|
||||
#ffi_value_var_name,
|
||||
)?;
|
||||
}
|
||||
)
|
||||
Ok(quote! {
|
||||
let #mut_access #name = <#ty as #crate_::host::FromFFIValue>::from_ffi_value(
|
||||
__function_context__,
|
||||
#ffi_value_var_name,
|
||||
)?;
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -326,19 +317,17 @@ fn generate_ffi_to_host_value<'a>(
|
||||
fn generate_host_function_call(sig: &Signature, version: u32, is_wasm_only: bool) -> TokenStream {
|
||||
let host_function_name = create_function_ident_with_version(&sig.ident, version);
|
||||
let result_var_name = generate_host_function_result_var_name(&sig.ident);
|
||||
let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram|
|
||||
ram.map(|(vr, vm)| quote!(#vr #vm))
|
||||
);
|
||||
let ref_and_mut =
|
||||
get_function_argument_types_ref_and_mut(sig).map(|ram| ram.map(|(vr, vm)| quote!(#vr #vm)));
|
||||
let names = get_function_argument_names(sig);
|
||||
|
||||
let var_access = names.zip(ref_and_mut)
|
||||
.map(|(n, ref_and_mut)| {
|
||||
quote!( #ref_and_mut #n )
|
||||
})
|
||||
let var_access = names
|
||||
.zip(ref_and_mut)
|
||||
.map(|(n, ref_and_mut)| quote!( #ref_and_mut #n ))
|
||||
// If this is a wasm only interface, we add the function context as last parameter.
|
||||
.chain(
|
||||
iter::from_fn(|| if is_wasm_only { Some(quote!(__function_context__)) } else { None })
|
||||
.take(1)
|
||||
.take(1),
|
||||
);
|
||||
|
||||
quote! {
|
||||
@@ -354,16 +343,15 @@ fn generate_host_function_result_var_name(name: &Ident) -> Ident {
|
||||
/// Generate the variable name that stores the FFI value.
|
||||
fn generate_ffi_value_var_name(pat: &Pat) -> Result<Ident> {
|
||||
match pat {
|
||||
Pat::Ident(pat_ident) => {
|
||||
Pat::Ident(pat_ident) =>
|
||||
if let Some(by_ref) = pat_ident.by_ref {
|
||||
Err(Error::new(by_ref.span(), "`ref` not supported!"))
|
||||
} else if let Some(sub_pattern) = &pat_ident.subpat {
|
||||
Err(Error::new(sub_pattern.0.span(), "Not supported!"))
|
||||
} else {
|
||||
Ok(Ident::new(&format!("{}_ffi_value", pat_ident.ident), Span::call_site()))
|
||||
}
|
||||
}
|
||||
_ => Err(Error::new(pat.span(), "Not supported as variable name!"))
|
||||
},
|
||||
_ => Err(Error::new(pat.span(), "Not supported as variable name!")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,25 +361,23 @@ fn generate_ffi_value_var_name(pat: &Pat) -> Result<Ident> {
|
||||
/// that the type implements `IntoPreAllocatedFFIValue`.
|
||||
fn generate_into_preallocated_ffi_value(sig: &Signature) -> Result<TokenStream> {
|
||||
let crate_ = generate_crate_access();
|
||||
let ref_and_mut = get_function_argument_types_ref_and_mut(sig).map(|ram|
|
||||
ram.and_then(|(vr, vm)| vm.map(|v| (vr, v)))
|
||||
);
|
||||
let ref_and_mut = get_function_argument_types_ref_and_mut(sig)
|
||||
.map(|ram| ram.and_then(|(vr, vm)| vm.map(|v| (vr, v))));
|
||||
let names_and_types = get_function_argument_names_and_types_without_ref(sig);
|
||||
|
||||
ref_and_mut.zip(names_and_types)
|
||||
ref_and_mut
|
||||
.zip(names_and_types)
|
||||
.filter_map(|(ram, (name, ty))| ram.map(|_| (name, ty)))
|
||||
.map(|(name, ty)| {
|
||||
let ffi_var_name = generate_ffi_value_var_name(&name)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
<#ty as #crate_::host::IntoPreallocatedFFIValue>::into_preallocated_ffi_value(
|
||||
#name,
|
||||
__function_context__,
|
||||
#ffi_var_name,
|
||||
)?;
|
||||
}
|
||||
)
|
||||
Ok(quote! {
|
||||
<#ty as #crate_::host::IntoPreallocatedFFIValue>::into_preallocated_ffi_value(
|
||||
#name,
|
||||
__function_context__,
|
||||
#ffi_var_name,
|
||||
)?;
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -401,7 +387,7 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream {
|
||||
let crate_ = generate_crate_access();
|
||||
|
||||
match &sig.output {
|
||||
ReturnType::Default => quote!( Ok(None) ),
|
||||
ReturnType::Default => quote!(Ok(None)),
|
||||
ReturnType::Type(_, ty) => {
|
||||
let result_var_name = generate_host_function_result_var_name(&sig.ident);
|
||||
|
||||
@@ -411,6 +397,6 @@ fn generate_return_value_into_wasm_value(sig: &Signature) -> TokenStream {
|
||||
__function_context__,
|
||||
).map(#crate_::sp_wasm_interface::IntoValue::into_value).map(Some)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
+27
-36
@@ -19,15 +19,14 @@
|
||||
//! default implementations and implements the trait for `&mut dyn Externalities`.
|
||||
|
||||
use crate::utils::{
|
||||
generate_crate_access,
|
||||
get_function_argument_types_without_ref,
|
||||
get_runtime_interface,
|
||||
create_function_ident_with_version,
|
||||
create_function_ident_with_version, generate_crate_access,
|
||||
get_function_argument_types_without_ref, get_runtime_interface,
|
||||
};
|
||||
|
||||
use syn::{
|
||||
ItemTrait, TraitItemMethod, Result, Error, fold::{self, Fold}, spanned::Spanned,
|
||||
Visibility, Receiver, Type, Generics,
|
||||
fold::{self, Fold},
|
||||
spanned::Spanned,
|
||||
Error, Generics, ItemTrait, Receiver, Result, TraitItemMethod, Type, Visibility,
|
||||
};
|
||||
|
||||
use proc_macro2::TokenStream;
|
||||
@@ -40,13 +39,11 @@ pub fn process(trait_def: &ItemTrait, is_wasm_only: bool) -> Result<TokenStream>
|
||||
let impl_trait = impl_trait_for_externalities(trait_def, is_wasm_only)?;
|
||||
let essential_trait_def = declare_essential_trait(trait_def)?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#impl_trait
|
||||
Ok(quote! {
|
||||
#impl_trait
|
||||
|
||||
#essential_trait_def
|
||||
}
|
||||
)
|
||||
#essential_trait_def
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts the given trait definition into the essential trait definition without method
|
||||
@@ -66,12 +63,10 @@ impl ToEssentialTraitDef {
|
||||
let mut errors = self.errors;
|
||||
let methods = self.methods;
|
||||
if let Some(first_error) = errors.pop() {
|
||||
Err(
|
||||
errors.into_iter().fold(first_error, |mut o, n| {
|
||||
o.combine(n);
|
||||
o
|
||||
})
|
||||
)
|
||||
Err(errors.into_iter().fold(first_error, |mut o, n| {
|
||||
o.combine(n);
|
||||
o
|
||||
}))
|
||||
} else {
|
||||
Ok(methods)
|
||||
}
|
||||
@@ -101,12 +96,12 @@ impl Fold for ToEssentialTraitDef {
|
||||
}
|
||||
|
||||
let arg_types = get_function_argument_types_without_ref(&method.sig);
|
||||
arg_types.filter_map(|ty|
|
||||
match *ty {
|
||||
arg_types
|
||||
.filter_map(|ty| match *ty {
|
||||
Type::ImplTrait(impl_trait) => Some(impl_trait),
|
||||
_ => None
|
||||
}
|
||||
).for_each(|invalid| self.push_error(&invalid, "`impl Trait` syntax not supported."));
|
||||
_ => None,
|
||||
})
|
||||
.for_each(|invalid| self.push_error(&invalid, "`impl Trait` syntax not supported."));
|
||||
|
||||
self.error_on_generic_parameters(&method.sig.generics);
|
||||
|
||||
@@ -145,13 +140,11 @@ fn declare_essential_trait(trait_def: &ItemTrait) -> Result<TokenStream> {
|
||||
}
|
||||
let methods = folder.into_methods()?;
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
trait #trait_ {
|
||||
#( #methods )*
|
||||
}
|
||||
Ok(quote! {
|
||||
trait #trait_ {
|
||||
#( #methods )*
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Implements the given trait definition for `dyn Externalities`.
|
||||
@@ -172,12 +165,10 @@ fn impl_trait_for_externalities(trait_def: &ItemTrait, is_wasm_only: bool) -> Re
|
||||
quote!( &mut dyn #crate_::Externalities )
|
||||
};
|
||||
|
||||
Ok(
|
||||
quote! {
|
||||
#[cfg(feature = "std")]
|
||||
impl #trait_ for #impl_type {
|
||||
#( #methods )*
|
||||
}
|
||||
Ok(quote! {
|
||||
#[cfg(feature = "std")]
|
||||
impl #trait_ for #impl_type {
|
||||
#( #methods )*
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,16 +17,19 @@
|
||||
|
||||
//! Util function used by this crate.
|
||||
|
||||
use proc_macro2::{TokenStream, Span};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
|
||||
use syn::{
|
||||
Ident, Error, Signature, Pat, PatType, FnArg, Type, token, TraitItemMethod, ItemTrait,
|
||||
TraitItem, parse_quote, spanned::Spanned, Result, Meta, NestedMeta, Lit, Attribute,
|
||||
parse_quote, spanned::Spanned, token, Attribute, Error, FnArg, Ident, ItemTrait, Lit, Meta,
|
||||
NestedMeta, Pat, PatType, Result, Signature, TraitItem, TraitItemMethod, Type,
|
||||
};
|
||||
|
||||
use proc_macro_crate::{crate_name, FoundCrate};
|
||||
|
||||
use std::{env, collections::{BTreeMap, btree_map::Entry}};
|
||||
use std::{
|
||||
collections::{btree_map::Entry, BTreeMap},
|
||||
env,
|
||||
};
|
||||
|
||||
use quote::quote;
|
||||
|
||||
@@ -53,8 +56,9 @@ impl<'a> RuntimeInterfaceFunction<'a> {
|
||||
pub fn latest_version(&self) -> (u32, &TraitItemMethod) {
|
||||
(
|
||||
self.latest_version,
|
||||
self.versions.get(&self.latest_version)
|
||||
.expect("If latest_version has a value, the key with this value is in the versions; qed")
|
||||
self.versions.get(&self.latest_version).expect(
|
||||
"If latest_version has a value, the key with this value is in the versions; qed",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -70,9 +74,12 @@ impl<'a> RuntimeInterface<'a> {
|
||||
}
|
||||
|
||||
pub fn all_versions(&self) -> impl Iterator<Item = (u32, &TraitItemMethod)> {
|
||||
self.items.iter().flat_map(|(_, item)| item.versions.iter()).map(|(v, i)| (*v, *i))
|
||||
self.items
|
||||
.iter()
|
||||
.flat_map(|(_, item)| item.versions.iter())
|
||||
.map(|(v, i)| (*v, *i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the include for the runtime-interface crate.
|
||||
pub fn generate_runtime_interface_include() -> TokenStream {
|
||||
@@ -88,16 +95,16 @@ pub fn generate_runtime_interface_include() -> TokenStream {
|
||||
Err(e) => {
|
||||
let err = Error::new(Span::call_site(), e).to_compile_error();
|
||||
quote!( #err )
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates the access to the `sp-runtime-interface` crate.
|
||||
pub fn generate_crate_access() -> TokenStream {
|
||||
if env::var("CARGO_PKG_NAME").unwrap() == "sp-runtime-interface" {
|
||||
quote!( sp_runtime_interface )
|
||||
quote!(sp_runtime_interface)
|
||||
} else {
|
||||
quote!( proc_macro_runtime_interface )
|
||||
quote!(proc_macro_runtime_interface)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,26 +116,14 @@ pub fn create_exchangeable_host_function_ident(name: &Ident) -> Ident {
|
||||
/// Create the host function identifier for the given function name.
|
||||
pub fn create_host_function_ident(name: &Ident, version: u32, trait_name: &Ident) -> Ident {
|
||||
Ident::new(
|
||||
&format!(
|
||||
"ext_{}_{}_version_{}",
|
||||
trait_name.to_string().to_snake_case(),
|
||||
name,
|
||||
version,
|
||||
),
|
||||
&format!("ext_{}_{}_version_{}", trait_name.to_string().to_snake_case(), name, version,),
|
||||
Span::call_site(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Create the host function identifier for the given function name.
|
||||
pub fn create_function_ident_with_version(name: &Ident, version: u32) -> Ident {
|
||||
Ident::new(
|
||||
&format!(
|
||||
"{}_version_{}",
|
||||
name,
|
||||
version,
|
||||
),
|
||||
Span::call_site(),
|
||||
)
|
||||
Ident::new(&format!("{}_version_{}", name, version,), Span::call_site())
|
||||
}
|
||||
|
||||
/// Returns the function arguments of the given `Signature`, minus any `self` arguments.
|
||||
@@ -143,10 +138,8 @@ pub fn get_function_arguments<'a>(sig: &'a Signature) -> impl Iterator<Item = Pa
|
||||
.map(|(i, arg)| {
|
||||
let mut res = arg.clone();
|
||||
if let Pat::Wild(wild) = &*arg.pat {
|
||||
let ident = Ident::new(
|
||||
&format!("__runtime_interface_generated_{}_", i),
|
||||
wild.span(),
|
||||
);
|
||||
let ident =
|
||||
Ident::new(&format!("__runtime_interface_generated_{}_", i), wild.span());
|
||||
|
||||
res.pat = Box::new(parse_quote!( #ident ))
|
||||
}
|
||||
@@ -170,12 +163,10 @@ pub fn get_function_argument_types<'a>(sig: &'a Signature) -> impl Iterator<Item
|
||||
pub fn get_function_argument_types_without_ref<'a>(
|
||||
sig: &'a Signature,
|
||||
) -> impl Iterator<Item = Box<Type>> + 'a {
|
||||
get_function_arguments(sig)
|
||||
.map(|pt| pt.ty)
|
||||
.map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => type_ref.elem,
|
||||
_ => ty,
|
||||
})
|
||||
get_function_arguments(sig).map(|pt| pt.ty).map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => type_ref.elem,
|
||||
_ => ty,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the function argument names and types, minus any `self`. If any of the arguments
|
||||
@@ -183,11 +174,10 @@ pub fn get_function_argument_types_without_ref<'a>(
|
||||
pub fn get_function_argument_names_and_types_without_ref<'a>(
|
||||
sig: &'a Signature,
|
||||
) -> impl Iterator<Item = (Box<Pat>, Box<Type>)> + 'a {
|
||||
get_function_arguments(sig)
|
||||
.map(|pt| match *pt.ty {
|
||||
Type::Reference(type_ref) => (pt.pat, type_ref.elem),
|
||||
_ => (pt.pat, pt.ty),
|
||||
})
|
||||
get_function_arguments(sig).map(|pt| match *pt.ty {
|
||||
Type::Reference(type_ref) => (pt.pat, type_ref.elem),
|
||||
_ => (pt.pat, pt.ty),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the `&`/`&mut` for all function argument types, minus the `self` arg. If a function
|
||||
@@ -195,23 +185,18 @@ pub fn get_function_argument_names_and_types_without_ref<'a>(
|
||||
pub fn get_function_argument_types_ref_and_mut<'a>(
|
||||
sig: &'a Signature,
|
||||
) -> impl Iterator<Item = Option<(token::And, Option<token::Mut>)>> + 'a {
|
||||
get_function_arguments(sig)
|
||||
.map(|pt| pt.ty)
|
||||
.map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => Some((type_ref.and_token, type_ref.mutability)),
|
||||
_ => None,
|
||||
})
|
||||
get_function_arguments(sig).map(|pt| pt.ty).map(|ty| match *ty {
|
||||
Type::Reference(type_ref) => Some((type_ref.and_token, type_ref.mutability)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns an iterator over all trait methods for the given trait definition.
|
||||
fn get_trait_methods<'a>(trait_def: &'a ItemTrait) -> impl Iterator<Item = &'a TraitItemMethod> {
|
||||
trait_def
|
||||
.items
|
||||
.iter()
|
||||
.filter_map(|i| match i {
|
||||
TraitItem::Method(ref method) => Some(method),
|
||||
_ => None,
|
||||
})
|
||||
trait_def.items.iter().filter_map(|i| match i {
|
||||
TraitItem::Method(ref method) => Some(method),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse version attribute.
|
||||
@@ -221,36 +206,34 @@ fn parse_version_attribute(version: &Attribute) -> Result<u32> {
|
||||
let meta = version.parse_meta()?;
|
||||
|
||||
let err = Err(Error::new(
|
||||
meta.span(),
|
||||
"Unexpected `version` attribute. The supported format is `#[version(1)]`",
|
||||
)
|
||||
);
|
||||
meta.span(),
|
||||
"Unexpected `version` attribute. The supported format is `#[version(1)]`",
|
||||
));
|
||||
|
||||
match meta {
|
||||
Meta::List(list) => {
|
||||
Meta::List(list) =>
|
||||
if list.nested.len() != 1 {
|
||||
err
|
||||
} else if let Some(NestedMeta::Lit(Lit::Int(i))) = list.nested.first() {
|
||||
i.base10_parse()
|
||||
} else {
|
||||
err
|
||||
}
|
||||
},
|
||||
},
|
||||
_ => err,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return item version (`#[version(X)]`) attribute, if present.
|
||||
fn get_item_version(item: &TraitItemMethod) -> Result<Option<u32>> {
|
||||
item.attrs.iter().find(|attr| attr.path.is_ident("version"))
|
||||
item.attrs
|
||||
.iter()
|
||||
.find(|attr| attr.path.is_ident("version"))
|
||||
.map(|attr| parse_version_attribute(attr))
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// Returns all runtime interface members, with versions.
|
||||
pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
|
||||
-> Result<RuntimeInterface<'a>>
|
||||
{
|
||||
pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait) -> Result<RuntimeInterface<'a>> {
|
||||
let mut functions: BTreeMap<syn::Ident, RuntimeInterfaceFunction<'a>> = BTreeMap::new();
|
||||
|
||||
for item in get_trait_methods(trait_def) {
|
||||
@@ -258,25 +241,26 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
|
||||
let version = get_item_version(item)?.unwrap_or(1);
|
||||
|
||||
match functions.entry(name.clone()) {
|
||||
Entry::Vacant(entry) => { entry.insert(RuntimeInterfaceFunction::new(version, item)); },
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(RuntimeInterfaceFunction::new(version, item));
|
||||
},
|
||||
Entry::Occupied(mut entry) => {
|
||||
if let Some(existing_item) = entry.get().versions.get(&version) {
|
||||
let mut err = Error::new(
|
||||
item.span(),
|
||||
"Duplicated version attribute",
|
||||
);
|
||||
let mut err = Error::new(item.span(), "Duplicated version attribute");
|
||||
err.combine(Error::new(
|
||||
existing_item.span(),
|
||||
"Previous version with the same number defined here",
|
||||
));
|
||||
|
||||
return Err(err);
|
||||
return Err(err)
|
||||
}
|
||||
|
||||
let interface_item = entry.get_mut();
|
||||
if interface_item.latest_version < version { interface_item.latest_version = version; }
|
||||
if interface_item.latest_version < version {
|
||||
interface_item.latest_version = version;
|
||||
}
|
||||
interface_item.versions.insert(version, item);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,8 +270,11 @@ pub fn get_runtime_interface<'a>(trait_def: &'a ItemTrait)
|
||||
if next_expected != *version {
|
||||
return Err(Error::new(
|
||||
item.span(),
|
||||
format!("Unexpected version attribute: missing version '{}' for this function", next_expected),
|
||||
));
|
||||
format!(
|
||||
"Unexpected version attribute: missing version '{}' for this function",
|
||||
next_expected
|
||||
),
|
||||
))
|
||||
}
|
||||
next_expected += 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user