mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-28 23:47:25 +00:00
Metadata V15: Expose types for the overarching Call, Event, Error enums (#14143)
* frame-metadata: Point to unreleased branch Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame: Generalize outer enum generation for events and errors Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame: Remove individual generation of outer enum events Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * primitives/traits: Add marker trait for outer runtime enums Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame: Derive Clone, PartialEq, Eq for RuntimeEvents only Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/pallet: Include `#[pallet::error]` enum into pallet parts Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * metadata-ir: Include call, event, error types Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/metadata: Include outer enum types in V15 metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/tests: Ensure `RuntimeError` includes `#[pallet::error]` parts Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/support: Document the reserved name for `RuntimeError` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame: Use self-generated `RuntimeEvent` for `GetRuntimeOuterEnumTypes` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/ui: Fix UI tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/support: Remove unused system path Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/ui: Unexpected field and reintroduce frame_system::Config for RuntimeCall Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/support: Remove `GetRuntimeOuterEnumTypes` marker trait Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/support: Remove `;` from macro Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update frame-metadata to point to unreleased branch Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Rename error_enum_ty to module_error_enum_ty Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update module_error_ty documentation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame: Implement from_dispatch_error Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/support: Adjust test to ModuleErrorType Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Fix clippy Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Improve documentation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame/tests: Check `from_dispatch_error` impl Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update frame-metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove the module_error_ty Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Apply fmt Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Revert unneeded parts Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Revert "Revert unneeded parts" This reverts commit b94bbd16078a025775a48da1095edec1705e6a4d. Revert "Apply fmt" This reverts commit 9b1c3e7b4ef27d32e10b35054a99916067e0397b. Revert "Remove the module_error_ty" This reverts commit 98de5b24653f9f9ec6ee842b749401b18a01758a. * Update frame-metadata to origin/master Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add outerEnums to the metadata Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Add tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Keep backwards compatibility for explicit pallet parts Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Rename tt_error_part to be more generic Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Increase recursion_limit to 1k Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Rename `fully_expanded` to `expanded` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Improve documentation Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust UI tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update UI tests Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update undefined_validate_unsigned_part.stderr UI test Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Adjust yet again Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Optimise macro expansions Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Use latest frame-metadata and rename `moduleErrorType` to `RuntimeError` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Fix comment Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Apply fmt Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update frame/support/procedural/src/construct_runtime/parse.rs Co-authored-by: Bastian Köcher <git@kchr.de> * Update frame/support/procedural/src/construct_runtime/parse.rs Co-authored-by: Bastian Köcher <git@kchr.de> * Update frame-metadata PR Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Remove `expanded` from error messages and fix typo Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Move docs to the function Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * ui: Use the intermed syntax for pallet parts Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * Update frame-metadata with latest release Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> * frame: Address feedback for `from_dispatch_error` Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> --------- Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -1,168 +0,0 @@
|
||||
// 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
|
||||
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
use syn::{Generics, Ident};
|
||||
|
||||
pub fn expand_outer_event(
|
||||
runtime: &Ident,
|
||||
pallet_decls: &[Pallet],
|
||||
scrate: &TokenStream,
|
||||
) -> syn::Result<TokenStream> {
|
||||
let mut event_variants = TokenStream::new();
|
||||
let mut event_conversions = TokenStream::new();
|
||||
let mut query_event_part_macros = Vec::new();
|
||||
|
||||
for pallet_decl in pallet_decls {
|
||||
if let Some(pallet_entry) = pallet_decl.find_part("Event") {
|
||||
let path = &pallet_decl.path;
|
||||
let pallet_name = &pallet_decl.name;
|
||||
let index = pallet_decl.index;
|
||||
let instance = pallet_decl.instance.as_ref();
|
||||
let generics = &pallet_entry.generics;
|
||||
|
||||
if instance.is_some() && generics.params.is_empty() {
|
||||
let msg = format!(
|
||||
"Instantiable pallet with no generic `Event` cannot \
|
||||
be constructed: pallet `{}` must have generic `Event`",
|
||||
pallet_name,
|
||||
);
|
||||
return Err(syn::Error::new(pallet_name.span(), msg))
|
||||
}
|
||||
|
||||
let part_is_generic = !generics.params.is_empty();
|
||||
let pallet_event = match (instance, part_is_generic) {
|
||||
(Some(inst), true) => quote!(#path::Event::<#runtime, #path::#inst>),
|
||||
(Some(inst), false) => quote!(#path::Event::<#path::#inst>),
|
||||
(None, true) => quote!(#path::Event::<#runtime>),
|
||||
(None, false) => quote!(#path::Event),
|
||||
};
|
||||
|
||||
event_variants.extend(expand_event_variant(
|
||||
runtime,
|
||||
pallet_decl,
|
||||
index,
|
||||
instance,
|
||||
generics,
|
||||
));
|
||||
event_conversions.extend(expand_event_conversion(scrate, pallet_decl, &pallet_event));
|
||||
query_event_part_macros.push(quote! {
|
||||
#path::__substrate_event_check::is_event_part_defined!(#pallet_name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(quote! {
|
||||
#( #query_event_part_macros )*
|
||||
|
||||
#[derive(
|
||||
Clone, PartialEq, Eq,
|
||||
#scrate::codec::Encode,
|
||||
#scrate::codec::Decode,
|
||||
#scrate::scale_info::TypeInfo,
|
||||
#scrate::RuntimeDebug,
|
||||
)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum RuntimeEvent {
|
||||
#event_variants
|
||||
}
|
||||
|
||||
#event_conversions
|
||||
})
|
||||
}
|
||||
|
||||
fn expand_event_variant(
|
||||
runtime: &Ident,
|
||||
pallet: &Pallet,
|
||||
index: u8,
|
||||
instance: Option<&Ident>,
|
||||
generics: &Generics,
|
||||
) -> TokenStream {
|
||||
let path = &pallet.path;
|
||||
let variant_name = &pallet.name;
|
||||
let part_is_generic = !generics.params.is_empty();
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
match instance {
|
||||
Some(inst) if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event<#runtime, #path::#inst>),
|
||||
},
|
||||
Some(inst) => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event<#path::#inst>),
|
||||
},
|
||||
None if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event<#runtime>),
|
||||
},
|
||||
None => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::Event),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_event_conversion(
|
||||
scrate: &TokenStream,
|
||||
pallet: &Pallet,
|
||||
pallet_event: &TokenStream,
|
||||
) -> TokenStream {
|
||||
let variant_name = &pallet.name;
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#attr
|
||||
impl From<#pallet_event> for RuntimeEvent {
|
||||
fn from(x: #pallet_event) -> Self {
|
||||
RuntimeEvent::#variant_name(x)
|
||||
}
|
||||
}
|
||||
#attr
|
||||
impl TryInto<#pallet_event> for RuntimeEvent {
|
||||
type Error = ();
|
||||
|
||||
fn try_into(self) -> #scrate::sp_std::result::Result<#pallet_event, Self::Error> {
|
||||
match self {
|
||||
Self::#variant_name(evt) => Ok(evt),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License
|
||||
|
||||
use crate::construct_runtime::Pallet;
|
||||
use crate::construct_runtime::{parse::PalletPath, Pallet};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::quote;
|
||||
use std::str::FromStr;
|
||||
@@ -26,6 +26,7 @@ pub fn expand_runtime_metadata(
|
||||
pallet_declarations: &[Pallet],
|
||||
scrate: &TokenStream,
|
||||
extrinsic: &TypePath,
|
||||
system_path: &PalletPath,
|
||||
) -> TokenStream {
|
||||
let pallets = pallet_declarations
|
||||
.iter()
|
||||
@@ -115,6 +116,13 @@ pub fn expand_runtime_metadata(
|
||||
},
|
||||
ty: #scrate::scale_info::meta_type::<#runtime>(),
|
||||
apis: (&rt).runtime_metadata(),
|
||||
outer_enums: #scrate::metadata_ir::OuterEnumsIR {
|
||||
call_enum_ty: #scrate::scale_info::meta_type::<
|
||||
<#runtime as #system_path::Config>::RuntimeCall
|
||||
>(),
|
||||
event_enum_ty: #scrate::scale_info::meta_type::<RuntimeEvent>(),
|
||||
error_enum_ty: #scrate::scale_info::meta_type::<RuntimeError>(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,24 +17,24 @@
|
||||
|
||||
mod call;
|
||||
mod config;
|
||||
mod event;
|
||||
mod freeze_reason;
|
||||
mod hold_reason;
|
||||
mod inherent;
|
||||
mod lock_id;
|
||||
mod metadata;
|
||||
mod origin;
|
||||
mod outer_enums;
|
||||
mod slash_reason;
|
||||
mod unsigned;
|
||||
|
||||
pub use call::expand_outer_dispatch;
|
||||
pub use config::expand_outer_config;
|
||||
pub use event::expand_outer_event;
|
||||
pub use freeze_reason::expand_outer_freeze_reason;
|
||||
pub use hold_reason::expand_outer_hold_reason;
|
||||
pub use inherent::expand_outer_inherent;
|
||||
pub use lock_id::expand_outer_lock_id;
|
||||
pub use metadata::expand_runtime_metadata;
|
||||
pub use origin::expand_outer_origin;
|
||||
pub use outer_enums::{expand_outer_enum, OuterEnumType};
|
||||
pub use slash_reason::expand_outer_slash_reason;
|
||||
pub use unsigned::expand_outer_validate_unsigned;
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
// 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
|
||||
|
||||
use crate::construct_runtime::Pallet;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, ToTokens};
|
||||
use std::str::FromStr;
|
||||
use syn::{Generics, Ident};
|
||||
|
||||
/// Represents the types supported for creating an outer enum.
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
pub enum OuterEnumType {
|
||||
/// Collects the Event enums from all pallets.
|
||||
Event,
|
||||
/// Collects the Error enums from all pallets.
|
||||
Error,
|
||||
}
|
||||
|
||||
impl OuterEnumType {
|
||||
/// The name of the structure this enum represents.
|
||||
fn struct_name(&self) -> &str {
|
||||
match self {
|
||||
OuterEnumType::Event => "RuntimeEvent",
|
||||
OuterEnumType::Error => "RuntimeError",
|
||||
}
|
||||
}
|
||||
|
||||
/// The name of the variant (ie `Event` or `Error`).
|
||||
fn variant_name(&self) -> &str {
|
||||
match self {
|
||||
OuterEnumType::Event => "Event",
|
||||
OuterEnumType::Error => "Error",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for OuterEnumType {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
match self {
|
||||
OuterEnumType::Event => quote!(Event).to_tokens(tokens),
|
||||
OuterEnumType::Error => quote!(Error).to_tokens(tokens),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an outer enum that encapsulates all pallets as variants.
|
||||
///
|
||||
/// Each variant represents a pallet and contains the corresponding type declared with either:
|
||||
/// - #[pallet::event] for the [`OuterEnumType::Event`] variant
|
||||
/// - #[pallet::error] for the [`OuterEnumType::Error`] variant
|
||||
///
|
||||
/// The name of the outer enum is prefixed with Runtime, resulting in names like RuntimeEvent
|
||||
/// or RuntimeError.
|
||||
///
|
||||
/// This structure facilitates the decoding process by leveraging the metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// The code generate looks like the following for [`OuterEnumType::Event`].
|
||||
///
|
||||
/// ```ignore
|
||||
/// enum RuntimeEvent {
|
||||
/// #[codec(index = 0)]
|
||||
/// System(pallet_system::Event),
|
||||
///
|
||||
/// #[codec(index = 5)]
|
||||
/// Balances(pallet_system::Event),
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Notice that the pallet index is preserved using the `#[codec(index = ..)]` attribute.
|
||||
pub fn expand_outer_enum(
|
||||
runtime: &Ident,
|
||||
pallet_decls: &[Pallet],
|
||||
scrate: &TokenStream,
|
||||
enum_ty: OuterEnumType,
|
||||
) -> syn::Result<TokenStream> {
|
||||
// Stores all pallet variants.
|
||||
let mut enum_variants = TokenStream::new();
|
||||
// Generates the enum conversion between the `Runtime` outer enum and the pallet's enum.
|
||||
let mut enum_conversions = TokenStream::new();
|
||||
// Specific for events to query via `is_event_part_defined!`.
|
||||
let mut query_enum_part_macros = Vec::new();
|
||||
|
||||
let enum_name_str = enum_ty.variant_name();
|
||||
let enum_name_ident = Ident::new(enum_ty.struct_name(), Span::call_site());
|
||||
|
||||
for pallet_decl in pallet_decls {
|
||||
let Some(pallet_entry) = pallet_decl.find_part(enum_name_str) else {
|
||||
continue
|
||||
};
|
||||
|
||||
let path = &pallet_decl.path;
|
||||
let pallet_name = &pallet_decl.name;
|
||||
let index = pallet_decl.index;
|
||||
let instance = pallet_decl.instance.as_ref();
|
||||
let generics = &pallet_entry.generics;
|
||||
|
||||
if instance.is_some() && generics.params.is_empty() {
|
||||
let msg = format!(
|
||||
"Instantiable pallet with no generic `{}` cannot \
|
||||
be constructed: pallet `{}` must have generic `{}`",
|
||||
enum_name_str, pallet_name, enum_name_str,
|
||||
);
|
||||
return Err(syn::Error::new(pallet_name.span(), msg))
|
||||
}
|
||||
|
||||
let part_is_generic = !generics.params.is_empty();
|
||||
let pallet_enum = match (instance, part_is_generic) {
|
||||
(Some(inst), true) => quote!(#path::#enum_ty::<#runtime, #path::#inst>),
|
||||
(Some(inst), false) => quote!(#path::#enum_ty::<#path::#inst>),
|
||||
(None, true) => quote!(#path::#enum_ty::<#runtime>),
|
||||
(None, false) => quote!(#path::#enum_ty),
|
||||
};
|
||||
|
||||
enum_variants.extend(expand_enum_variant(
|
||||
runtime,
|
||||
pallet_decl,
|
||||
index,
|
||||
instance,
|
||||
generics,
|
||||
enum_ty,
|
||||
));
|
||||
enum_conversions.extend(expand_enum_conversion(
|
||||
scrate,
|
||||
pallet_decl,
|
||||
&pallet_enum,
|
||||
&enum_name_ident,
|
||||
));
|
||||
|
||||
if enum_ty == OuterEnumType::Event {
|
||||
query_enum_part_macros.push(quote! {
|
||||
#path::__substrate_event_check::is_event_part_defined!(#pallet_name);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Derives specific for the event.
|
||||
let event_custom_derives =
|
||||
if enum_ty == OuterEnumType::Event { quote!(Clone, PartialEq, Eq,) } else { quote!() };
|
||||
|
||||
// Implementation specific for errors.
|
||||
let error_custom_impl = generate_error_impl(scrate, enum_ty);
|
||||
|
||||
Ok(quote! {
|
||||
#( #query_enum_part_macros )*
|
||||
|
||||
#[derive(
|
||||
#event_custom_derives
|
||||
#scrate::codec::Encode,
|
||||
#scrate::codec::Decode,
|
||||
#scrate::scale_info::TypeInfo,
|
||||
#scrate::RuntimeDebug,
|
||||
)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum #enum_name_ident {
|
||||
#enum_variants
|
||||
}
|
||||
|
||||
#enum_conversions
|
||||
|
||||
#error_custom_impl
|
||||
})
|
||||
}
|
||||
|
||||
fn expand_enum_variant(
|
||||
runtime: &Ident,
|
||||
pallet: &Pallet,
|
||||
index: u8,
|
||||
instance: Option<&Ident>,
|
||||
generics: &Generics,
|
||||
enum_ty: OuterEnumType,
|
||||
) -> TokenStream {
|
||||
let path = &pallet.path;
|
||||
let variant_name = &pallet.name;
|
||||
let part_is_generic = !generics.params.is_empty();
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
match instance {
|
||||
Some(inst) if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::#enum_ty<#runtime, #path::#inst>),
|
||||
},
|
||||
Some(inst) => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::#enum_ty<#path::#inst>),
|
||||
},
|
||||
None if part_is_generic => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::#enum_ty<#runtime>),
|
||||
},
|
||||
None => quote! {
|
||||
#attr
|
||||
#[codec(index = #index)]
|
||||
#variant_name(#path::#enum_ty),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn expand_enum_conversion(
|
||||
scrate: &TokenStream,
|
||||
pallet: &Pallet,
|
||||
pallet_enum: &TokenStream,
|
||||
enum_name_ident: &Ident,
|
||||
) -> TokenStream {
|
||||
let variant_name = &pallet.name;
|
||||
let attr = pallet.cfg_pattern.iter().fold(TokenStream::new(), |acc, pattern| {
|
||||
let attr = TokenStream::from_str(&format!("#[cfg({})]", pattern.original()))
|
||||
.expect("was successfully parsed before; qed");
|
||||
quote! {
|
||||
#acc
|
||||
#attr
|
||||
}
|
||||
});
|
||||
|
||||
quote! {
|
||||
#attr
|
||||
impl From<#pallet_enum> for #enum_name_ident {
|
||||
fn from(x: #pallet_enum) -> Self {
|
||||
#enum_name_ident
|
||||
::#variant_name(x)
|
||||
}
|
||||
}
|
||||
#attr
|
||||
impl TryInto<#pallet_enum> for #enum_name_ident {
|
||||
type Error = ();
|
||||
|
||||
fn try_into(self) -> #scrate::sp_std::result::Result<#pallet_enum, Self::Error> {
|
||||
match self {
|
||||
Self::#variant_name(evt) => Ok(evt),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_error_impl(scrate: &TokenStream, enum_ty: OuterEnumType) -> TokenStream {
|
||||
// Implementation is specific to `Error`s.
|
||||
if enum_ty == OuterEnumType::Event {
|
||||
return quote! {}
|
||||
}
|
||||
|
||||
let enum_name_ident = Ident::new(enum_ty.struct_name(), Span::call_site());
|
||||
|
||||
quote! {
|
||||
impl #enum_name_ident {
|
||||
/// Optionally convert the `DispatchError` into the `RuntimeError`.
|
||||
///
|
||||
/// Returns `Some` if the error matches the `DispatchError::Module` variant, otherwise `None`.
|
||||
pub fn from_dispatch_error(err: #scrate::sp_runtime::DispatchError) -> Option<Self> {
|
||||
let #scrate::sp_runtime::DispatchError::Module(module_error) = err else { return None };
|
||||
|
||||
let bytes = #scrate::codec::Encode::encode(&module_error);
|
||||
#scrate::codec::Decode::decode(&mut &bytes[..]).ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user