mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 23:57:56 +00:00
002d9260f9
**Update:** Pushed additional changes based on the review comments. **This pull request fixes various spelling mistakes in this repository.** Most of the changes are contained in the first **3** commits: - `Fix spelling mistakes in comments and docs` - `Fix spelling mistakes in test names` - `Fix spelling mistakes in error messages, panic messages, logs and tracing` Other source code spelling mistakes are separated into individual commits for easier reviewing: - `Fix the spelling of 'authority'` - `Fix the spelling of 'REASONABLE_HEADERS_IN_JUSTIFICATION_ANCESTRY'` - `Fix the spelling of 'prev_enqueud_messages'` - `Fix the spelling of 'endpoint'` - `Fix the spelling of 'children'` - `Fix the spelling of 'PenpalSiblingSovereignAccount'` - `Fix the spelling of 'PenpalSudoAccount'` - `Fix the spelling of 'insufficient'` - `Fix the spelling of 'PalletXcmExtrinsicsBenchmark'` - `Fix the spelling of 'subtracted'` - `Fix the spelling of 'CandidatePendingAvailability'` - `Fix the spelling of 'exclusive'` - `Fix the spelling of 'until'` - `Fix the spelling of 'discriminator'` - `Fix the spelling of 'nonexistent'` - `Fix the spelling of 'subsystem'` - `Fix the spelling of 'indices'` - `Fix the spelling of 'committed'` - `Fix the spelling of 'topology'` - `Fix the spelling of 'response'` - `Fix the spelling of 'beneficiary'` - `Fix the spelling of 'formatted'` - `Fix the spelling of 'UNKNOWN_PROOF_REQUEST'` - `Fix the spelling of 'succeeded'` - `Fix the spelling of 'reopened'` - `Fix the spelling of 'proposer'` - `Fix the spelling of 'InstantiationNonce'` - `Fix the spelling of 'depositor'` - `Fix the spelling of 'expiration'` - `Fix the spelling of 'phantom'` - `Fix the spelling of 'AggregatedKeyValue'` - `Fix the spelling of 'randomness'` - `Fix the spelling of 'defendant'` - `Fix the spelling of 'AquaticMammal'` - `Fix the spelling of 'transactions'` - `Fix the spelling of 'PassingTracingSubscriber'` - `Fix the spelling of 'TxSignaturePayload'` - `Fix the spelling of 'versioning'` - `Fix the spelling of 'descendant'` - `Fix the spelling of 'overridden'` - `Fix the spelling of 'network'` Let me know if this structure is adequate. **Note:** The usage of the words `Merkle`, `Merkelize`, `Merklization`, `Merkelization`, `Merkleization`, is somewhat inconsistent but I left it as it is. ~~**Note:** In some places the term `Receival` is used to refer to message reception, IMO `Reception` is the correct word here, but I left it as it is.~~ ~~**Note:** In some places the term `Overlayed` is used instead of the more acceptable version `Overlaid` but I also left it as it is.~~ ~~**Note:** In some places the term `Applyable` is used instead of the correct version `Applicable` but I also left it as it is.~~ **Note:** Some usage of British vs American english e.g. `judgement` vs `judgment`, `initialise` vs `initialize`, `optimise` vs `optimize` etc. are both present in different places, but I suppose that's understandable given the number of contributors. ~~**Note:** There is a spelling mistake in `.github/CODEOWNERS` but it triggers errors in CI when I make changes to it, so I left it as it is.~~
564 lines
15 KiB
Rust
564 lines
15 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! Code for the `#[dynamic_params]`, `#[dynamic_pallet_params]` and
|
|
//! `#[dynamic_aggregated_params_internal]` macros.
|
|
|
|
use frame_support_procedural_tools::generate_access_from_frame_or_crate;
|
|
use inflector::Inflector;
|
|
use proc_macro2::{Span, TokenStream};
|
|
use quote::{format_ident, quote, ToTokens};
|
|
use syn::{parse2, spanned::Spanned, visit_mut, visit_mut::VisitMut, Result, Token};
|
|
|
|
/// Parse and expand a `#[dynamic_params(..)]` module.
|
|
pub fn dynamic_params(attr: TokenStream, item: TokenStream) -> Result<TokenStream> {
|
|
DynamicParamModAttr::parse(attr, item).map(ToTokens::into_token_stream)
|
|
}
|
|
|
|
/// Parse and expand `#[dynamic_pallet_params(..)]` attribute.
|
|
pub fn dynamic_pallet_params(attr: TokenStream, item: TokenStream) -> Result<TokenStream> {
|
|
DynamicPalletParamAttr::parse(attr, item).map(ToTokens::into_token_stream)
|
|
}
|
|
|
|
/// Parse and expand `#[dynamic_aggregated_params_internal]` attribute.
|
|
pub fn dynamic_aggregated_params_internal(
|
|
_attr: TokenStream,
|
|
item: TokenStream,
|
|
) -> Result<TokenStream> {
|
|
parse2::<DynamicParamAggregatedEnum>(item).map(ToTokens::into_token_stream)
|
|
}
|
|
|
|
/// A top `#[dynamic_params(..)]` attribute together with a mod.
|
|
#[derive(derive_syn_parse::Parse)]
|
|
pub struct DynamicParamModAttr {
|
|
params_mod: syn::ItemMod,
|
|
meta: DynamicParamModAttrMeta,
|
|
}
|
|
|
|
/// The inner meta of a `#[dynamic_params(..)]` attribute.
|
|
#[derive(derive_syn_parse::Parse)]
|
|
pub struct DynamicParamModAttrMeta {
|
|
name: syn::Ident,
|
|
_comma: Option<Token![,]>,
|
|
#[parse_if(_comma.is_some())]
|
|
params_pallet: Option<syn::Type>,
|
|
}
|
|
|
|
impl DynamicParamModAttr {
|
|
pub fn parse(attr: TokenStream, item: TokenStream) -> Result<Self> {
|
|
let params_mod = parse2(item)?;
|
|
let meta = parse2(attr)?;
|
|
Ok(Self { params_mod, meta })
|
|
}
|
|
|
|
pub fn inner_mods(&self) -> Vec<syn::ItemMod> {
|
|
self.params_mod.content.as_ref().map_or(Vec::new(), |(_, items)| {
|
|
items
|
|
.iter()
|
|
.filter_map(|i| match i {
|
|
syn::Item::Mod(m) => Some(m),
|
|
_ => None,
|
|
})
|
|
.cloned()
|
|
.collect()
|
|
})
|
|
}
|
|
}
|
|
|
|
impl ToTokens for DynamicParamModAttr {
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
let scrate = match crate_access() {
|
|
Ok(path) => path,
|
|
Err(err) => return tokens.extend(err),
|
|
};
|
|
let (mut params_mod, name) = (self.params_mod.clone(), &self.meta.name);
|
|
let dynam_params_ident = ¶ms_mod.ident;
|
|
|
|
let mut quoted_enum = quote! {};
|
|
for m in self.inner_mods() {
|
|
let aggregate_name =
|
|
syn::Ident::new(&m.ident.to_string().to_class_case(), m.ident.span());
|
|
let mod_name = &m.ident;
|
|
|
|
let mut attrs = m.attrs.clone();
|
|
attrs.retain(|attr| !attr.path().is_ident("dynamic_pallet_params"));
|
|
if let Err(err) = ensure_codec_index(&attrs, m.span()) {
|
|
tokens.extend(err.into_compile_error());
|
|
return
|
|
}
|
|
|
|
quoted_enum.extend(quote! {
|
|
#(#attrs)*
|
|
#aggregate_name(#dynam_params_ident::#mod_name::Parameters),
|
|
});
|
|
}
|
|
|
|
// Inject the outer args into the inner `#[dynamic_pallet_params(..)]` attribute.
|
|
if let Some(params_pallet) = &self.meta.params_pallet {
|
|
MacroInjectArgs { runtime_params: name.clone(), params_pallet: params_pallet.clone() }
|
|
.visit_item_mod_mut(&mut params_mod);
|
|
}
|
|
|
|
tokens.extend(quote! {
|
|
#params_mod
|
|
|
|
#[#scrate::dynamic_params::dynamic_aggregated_params_internal]
|
|
pub enum #name {
|
|
#quoted_enum
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/// Ensure there is a `#[codec(index = ..)]` attribute.
|
|
fn ensure_codec_index(attrs: &Vec<syn::Attribute>, span: Span) -> Result<()> {
|
|
let mut found = false;
|
|
|
|
for attr in attrs.iter() {
|
|
if attr.path().is_ident("codec") {
|
|
let meta: syn::ExprAssign = attr.parse_args()?;
|
|
if meta.left.to_token_stream().to_string() == "index" {
|
|
found = true;
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
Err(syn::Error::new(span, "Missing explicit `#[codec(index = ..)]` attribute"))
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Used to inject arguments into the inner `#[dynamic_pallet_params(..)]` attribute.
|
|
///
|
|
/// This allows the outer `#[dynamic_params(..)]` attribute to specify some arguments that don't
|
|
/// need to be repeated every time.
|
|
struct MacroInjectArgs {
|
|
runtime_params: syn::Ident,
|
|
params_pallet: syn::Type,
|
|
}
|
|
impl VisitMut for MacroInjectArgs {
|
|
fn visit_item_mod_mut(&mut self, item: &mut syn::ItemMod) {
|
|
// Check if the mod has a `#[dynamic_pallet_params(..)]` attribute.
|
|
let attr = item.attrs.iter_mut().find(|attr| attr.path().is_ident("dynamic_pallet_params"));
|
|
|
|
if let Some(attr) = attr {
|
|
match &attr.meta {
|
|
syn::Meta::Path(path) =>
|
|
assert_eq!(path.to_token_stream().to_string(), "dynamic_pallet_params"),
|
|
_ => (),
|
|
}
|
|
|
|
let runtime_params = &self.runtime_params;
|
|
let params_pallet = &self.params_pallet;
|
|
|
|
attr.meta = syn::parse2::<syn::Meta>(quote! {
|
|
dynamic_pallet_params(#runtime_params, #params_pallet)
|
|
})
|
|
.unwrap()
|
|
.into();
|
|
}
|
|
|
|
visit_mut::visit_item_mod_mut(self, item);
|
|
}
|
|
}
|
|
/// The helper attribute of a `#[dynamic_pallet_params(runtime_params, params_pallet)]`
|
|
/// attribute.
|
|
#[derive(derive_syn_parse::Parse)]
|
|
pub struct DynamicPalletParamAttr {
|
|
inner_mod: syn::ItemMod,
|
|
meta: DynamicPalletParamAttrMeta,
|
|
}
|
|
|
|
/// The inner meta of a `#[dynamic_pallet_params(..)]` attribute.
|
|
#[derive(derive_syn_parse::Parse)]
|
|
pub struct DynamicPalletParamAttrMeta {
|
|
runtime_params: syn::Ident,
|
|
_comma: Token![,],
|
|
parameter_pallet: syn::Type,
|
|
}
|
|
|
|
impl DynamicPalletParamAttr {
|
|
pub fn parse(attr: TokenStream, item: TokenStream) -> Result<Self> {
|
|
Ok(Self { inner_mod: parse2(item)?, meta: parse2(attr)? })
|
|
}
|
|
|
|
pub fn statics(&self) -> Vec<syn::ItemStatic> {
|
|
self.inner_mod.content.as_ref().map_or(Vec::new(), |(_, items)| {
|
|
items
|
|
.iter()
|
|
.filter_map(|i| match i {
|
|
syn::Item::Static(s) => Some(s),
|
|
_ => None,
|
|
})
|
|
.cloned()
|
|
.collect()
|
|
})
|
|
}
|
|
}
|
|
|
|
impl ToTokens for DynamicPalletParamAttr {
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
let scrate = match crate_access() {
|
|
Ok(path) => path,
|
|
Err(err) => return tokens.extend(err),
|
|
};
|
|
let (params_mod, parameter_pallet, runtime_params) =
|
|
(&self.inner_mod, &self.meta.parameter_pallet, &self.meta.runtime_params);
|
|
|
|
let aggregate_name =
|
|
syn::Ident::new(¶ms_mod.ident.to_string().to_class_case(), params_mod.ident.span());
|
|
let (mod_name, vis) = (¶ms_mod.ident, ¶ms_mod.vis);
|
|
let statics = self.statics();
|
|
|
|
let (mut key_names, mut key_values, mut defaults, mut attrs, mut value_types): (
|
|
Vec<_>,
|
|
Vec<_>,
|
|
Vec<_>,
|
|
Vec<_>,
|
|
Vec<_>,
|
|
) = Default::default();
|
|
|
|
for s in statics.iter() {
|
|
if let Err(err) = ensure_codec_index(&s.attrs, s.span()) {
|
|
tokens.extend(err.into_compile_error());
|
|
return
|
|
}
|
|
|
|
key_names.push(&s.ident);
|
|
key_values.push(format_ident!("{}Value", &s.ident));
|
|
defaults.push(&s.expr);
|
|
attrs.push(&s.attrs);
|
|
value_types.push(&s.ty);
|
|
}
|
|
|
|
let key_ident = syn::Ident::new("ParametersKey", params_mod.ident.span());
|
|
let value_ident = syn::Ident::new("ParametersValue", params_mod.ident.span());
|
|
let runtime_key_ident = format_ident!("{}Key", runtime_params);
|
|
let runtime_value_ident = format_ident!("{}Value", runtime_params);
|
|
|
|
tokens.extend(quote! {
|
|
pub mod #mod_name {
|
|
use super::*;
|
|
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::__private::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis enum Parameters {
|
|
#(
|
|
#(#attrs)*
|
|
#key_names(#key_names, Option<#value_types>),
|
|
)*
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::__private::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis enum #key_ident {
|
|
#(
|
|
#(#attrs)*
|
|
#key_names(#key_names),
|
|
)*
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::__private::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis enum #value_ident {
|
|
#(
|
|
#(#attrs)*
|
|
#key_names(#value_types),
|
|
)*
|
|
}
|
|
|
|
impl #scrate::traits::dynamic_params::AggregatedKeyValue for Parameters {
|
|
type Key = #key_ident;
|
|
type Value = #value_ident;
|
|
|
|
fn into_parts(self) -> (Self::Key, Option<Self::Value>) {
|
|
match self {
|
|
#(
|
|
Parameters::#key_names(key, value) => {
|
|
(#key_ident::#key_names(key), value.map(#value_ident::#key_names))
|
|
},
|
|
)*
|
|
}
|
|
}
|
|
}
|
|
|
|
#(
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::__private::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis struct #key_names;
|
|
|
|
impl #scrate::__private::Get<#value_types> for #key_names {
|
|
fn get() -> #value_types {
|
|
match
|
|
<#parameter_pallet as
|
|
#scrate::storage::StorageMap<#runtime_key_ident, #runtime_value_ident>
|
|
>::get(#runtime_key_ident::#aggregate_name(#key_ident::#key_names(#key_names)))
|
|
{
|
|
Some(#runtime_value_ident::#aggregate_name(
|
|
#value_ident::#key_names(inner))) => inner,
|
|
Some(_) => {
|
|
#scrate::defensive!("Unexpected value type at key - returning default");
|
|
#defaults
|
|
},
|
|
None => #defaults,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl #scrate::traits::dynamic_params::Key for #key_names {
|
|
type Value = #value_types;
|
|
type WrappedValue = #key_values;
|
|
}
|
|
|
|
impl From<#key_names> for #key_ident {
|
|
fn from(key: #key_names) -> Self {
|
|
#key_ident::#key_names(key)
|
|
}
|
|
}
|
|
|
|
impl TryFrom<#key_ident> for #key_names {
|
|
type Error = ();
|
|
|
|
fn try_from(key: #key_ident) -> Result<Self, Self::Error> {
|
|
match key {
|
|
#key_ident::#key_names(key) => Ok(key),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::sp_runtime::RuntimeDebug,
|
|
)]
|
|
#vis struct #key_values(pub #value_types);
|
|
|
|
impl From<#key_values> for #value_ident {
|
|
fn from(value: #key_values) -> Self {
|
|
#value_ident::#key_names(value.0)
|
|
}
|
|
}
|
|
|
|
impl From<(#key_names, #value_types)> for Parameters {
|
|
fn from((key, value): (#key_names, #value_types)) -> Self {
|
|
Parameters::#key_names(key, Some(value))
|
|
}
|
|
}
|
|
|
|
impl From<#key_names> for Parameters {
|
|
fn from(key: #key_names) -> Self {
|
|
Parameters::#key_names(key, None)
|
|
}
|
|
}
|
|
|
|
impl TryFrom<#value_ident> for #key_values {
|
|
type Error = ();
|
|
|
|
fn try_from(value: #value_ident) -> Result<Self, Self::Error> {
|
|
match value {
|
|
#value_ident::#key_names(value) => Ok(#key_values(value)),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<#key_values> for #value_types {
|
|
fn from(value: #key_values) -> Self {
|
|
value.0
|
|
}
|
|
}
|
|
)*
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
#[derive(derive_syn_parse::Parse)]
|
|
pub struct DynamicParamAggregatedEnum {
|
|
aggregated_enum: syn::ItemEnum,
|
|
}
|
|
|
|
impl ToTokens for DynamicParamAggregatedEnum {
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
let scrate = match crate_access() {
|
|
Ok(path) => path,
|
|
Err(err) => return tokens.extend(err),
|
|
};
|
|
let params_enum = &self.aggregated_enum;
|
|
let (name, vis) = (¶ms_enum.ident, ¶ms_enum.vis);
|
|
|
|
let (mut indices, mut param_names, mut param_types): (Vec<_>, Vec<_>, Vec<_>) =
|
|
Default::default();
|
|
let mut attributes = Vec::new();
|
|
for (i, variant) in params_enum.variants.iter().enumerate() {
|
|
indices.push(i);
|
|
param_names.push(&variant.ident);
|
|
attributes.push(&variant.attrs);
|
|
|
|
param_types.push(match &variant.fields {
|
|
syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
|
|
_ => {
|
|
*tokens = quote! { compile_error!("Only unnamed enum variants with one inner item are supported") };
|
|
return
|
|
},
|
|
});
|
|
}
|
|
|
|
let params_key_ident = format_ident!("{}Key", params_enum.ident);
|
|
let params_value_ident = format_ident!("{}Value", params_enum.ident);
|
|
|
|
tokens.extend(quote! {
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::sp_runtime::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis enum #name {
|
|
#(
|
|
//#[codec(index = #indices)]
|
|
#(#attributes)*
|
|
#param_names(#param_types),
|
|
)*
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::sp_runtime::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis enum #params_key_ident {
|
|
#(
|
|
#(#attributes)*
|
|
#param_names(<#param_types as #scrate::traits::dynamic_params::AggregatedKeyValue>::Key),
|
|
)*
|
|
}
|
|
|
|
#[doc(hidden)]
|
|
#[derive(
|
|
Clone,
|
|
PartialEq,
|
|
Eq,
|
|
#scrate::__private::codec::Encode,
|
|
#scrate::__private::codec::Decode,
|
|
#scrate::__private::codec::MaxEncodedLen,
|
|
#scrate::sp_runtime::RuntimeDebug,
|
|
#scrate::__private::scale_info::TypeInfo
|
|
)]
|
|
#vis enum #params_value_ident {
|
|
#(
|
|
#(#attributes)*
|
|
#param_names(<#param_types as #scrate::traits::dynamic_params::AggregatedKeyValue>::Value),
|
|
)*
|
|
}
|
|
|
|
impl #scrate::traits::dynamic_params::AggregatedKeyValue for #name {
|
|
type Key = #params_key_ident;
|
|
type Value = #params_value_ident;
|
|
|
|
fn into_parts(self) -> (Self::Key, Option<Self::Value>) {
|
|
match self {
|
|
#(
|
|
#name::#param_names(parameter) => {
|
|
let (key, value) = parameter.into_parts();
|
|
(#params_key_ident::#param_names(key), value.map(#params_value_ident::#param_names))
|
|
},
|
|
)*
|
|
}
|
|
}
|
|
}
|
|
|
|
#(
|
|
impl ::core::convert::From<<#param_types as #scrate::traits::dynamic_params::AggregatedKeyValue>::Key> for #params_key_ident {
|
|
fn from(key: <#param_types as #scrate::traits::dynamic_params::AggregatedKeyValue>::Key) -> Self {
|
|
#params_key_ident::#param_names(key)
|
|
}
|
|
}
|
|
|
|
impl ::core::convert::TryFrom<#params_value_ident> for <#param_types as #scrate::traits::dynamic_params::AggregatedKeyValue>::Value {
|
|
type Error = ();
|
|
|
|
fn try_from(value: #params_value_ident) -> Result<Self, Self::Error> {
|
|
match value {
|
|
#params_value_ident::#param_names(value) => Ok(value),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|
|
)*
|
|
});
|
|
}
|
|
}
|
|
|
|
/// Get access to the current crate and convert the error to a compile error.
|
|
fn crate_access() -> core::result::Result<syn::Path, TokenStream> {
|
|
generate_access_from_frame_or_crate("frame-support").map_err(|e| e.to_compile_error())
|
|
}
|