diff --git a/substrate/frame/example/src/lib.rs b/substrate/frame/example/src/lib.rs index 230aacbc01..4b10804fb1 100644 --- a/substrate/frame/example/src/lib.rs +++ b/substrate/frame/example/src/lib.rs @@ -256,7 +256,7 @@ use sp_std::marker::PhantomData; use frame_support::{ - dispatch::{DispatchResult, IsSubType}, decl_module, decl_storage, decl_event, + dispatch::DispatchResult, decl_module, decl_storage, decl_event, traits::IsSubType, weights::{DispatchClass, ClassifyDispatch, WeighData, Weight, PaysFee, Pays}, }; use sp_std::prelude::*; diff --git a/substrate/frame/proxy/src/lib.rs b/substrate/frame/proxy/src/lib.rs index 840c5aa5ab..7649fe0ad4 100644 --- a/substrate/frame/proxy/src/lib.rs +++ b/substrate/frame/proxy/src/lib.rs @@ -44,9 +44,8 @@ use sp_io::hashing::blake2_256; use sp_runtime::{DispatchResult, traits::{Dispatchable, Zero, Hash, Member, Saturating}}; use frame_support::{ decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug, traits::{ - Get, ReservableCurrency, Currency, InstanceFilter, OriginTrait, IsType, - }, weights::{Weight, GetDispatchInfo}, - dispatch::{PostDispatchInfo, IsSubType}, storage::IterableStorageMap, + Get, ReservableCurrency, Currency, InstanceFilter, OriginTrait, IsType, IsSubType, + }, weights::{Weight, GetDispatchInfo}, dispatch::PostDispatchInfo, storage::IterableStorageMap, }; use frame_system::{self as system, ensure_signed}; use frame_support::dispatch::DispatchError; diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 9436dfd3bb..cd3a71ffab 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -294,12 +294,12 @@ use frame_support::{ weights::{Weight, constants::{WEIGHT_PER_MICROS, WEIGHT_PER_NANOS}}, storage::IterableStorageMap, dispatch::{ - IsSubType, DispatchResult, DispatchResultWithPostInfo, DispatchErrorWithPostInfo, + DispatchResult, DispatchResultWithPostInfo, DispatchErrorWithPostInfo, WithPostDispatchInfo, }, traits::{ Currency, LockIdentifier, LockableCurrency, WithdrawReasons, OnUnbalanced, Imbalance, Get, - UnixTime, EstimateNextNewSession, EnsureOrigin, CurrencyToVote, + UnixTime, EstimateNextNewSession, EnsureOrigin, CurrencyToVote, IsSubType, } }; use pallet_session::historical; diff --git a/substrate/frame/support/src/dispatch.rs b/substrate/frame/support/src/dispatch.rs index 02e03ec6e6..057bba6b8f 100644 --- a/substrate/frame/support/src/dispatch.rs +++ b/substrate/frame/support/src/dispatch.rs @@ -1900,10 +1900,6 @@ macro_rules! decl_module { } } -pub trait IsSubType { - fn is_sub_type(&self) -> Option<&T>; -} - /// Implement a meta-dispatch module to dispatch to other dispatchers. #[macro_export] macro_rules! impl_outer_dispatch { @@ -2001,7 +1997,7 @@ macro_rules! impl_outer_dispatch { } $( - impl $crate::dispatch::IsSubType<$crate::dispatch::CallableCallFor<$camelcase, $runtime>> for $call_type { + impl $crate::traits::IsSubType<$crate::dispatch::CallableCallFor<$camelcase, $runtime>> for $call_type { #[allow(unreachable_patterns)] fn is_sub_type(&self) -> Option<&$crate::dispatch::CallableCallFor<$camelcase, $runtime>> { match *self { diff --git a/substrate/frame/support/src/inherent.rs b/substrate/frame/support/src/inherent.rs index e9b0c22692..83a1872ab4 100644 --- a/substrate/frame/support/src/inherent.rs +++ b/substrate/frame/support/src/inherent.rs @@ -74,7 +74,7 @@ macro_rules! impl_outer_inherent { fn check_extrinsics(&self, block: &$block) -> $crate::inherent::CheckInherentsResult { use $crate::inherent::{ProvideInherent, IsFatalError}; - use $crate::dispatch::IsSubType; + use $crate::traits::IsSubType; let mut result = $crate::inherent::CheckInherentsResult::new(); for xt in block.extrinsics() { @@ -141,7 +141,7 @@ macro_rules! impl_outer_inherent { mod tests { use super::*; use sp_runtime::{traits, testing::{Header, self}}; - use crate::dispatch::IsSubType; + use crate::traits::IsSubType; #[derive(codec::Encode, codec::Decode, Clone, PartialEq, Eq, Debug, serde::Serialize)] enum Call { diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 889ff15066..ed79abc5b2 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -77,7 +77,7 @@ pub use self::storage::{ StorageValue, StorageMap, StorageDoubleMap, StoragePrefixedMap, IterableStorageMap, IterableStorageDoubleMap, migration }; -pub use self::dispatch::{Parameter, Callable, IsSubType}; +pub use self::dispatch::{Parameter, Callable}; pub use sp_runtime::{self, ConsensusEngineId, print, traits::Printable}; /// A type that cannot be instantiated. diff --git a/substrate/frame/support/src/traits.rs b/substrate/frame/support/src/traits.rs index 88071f9f00..377bfaa56a 100644 --- a/substrate/frame/support/src/traits.rs +++ b/substrate/frame/support/src/traits.rs @@ -1708,8 +1708,8 @@ impl IsType for T { /// E.g. for module MyModule default instance will have prefix "MyModule" and other instances /// "InstanceNMyModule". pub trait Instance: 'static { - /// Unique module prefix. E.g. "InstanceNMyModule" or "MyModule" - const PREFIX: &'static str ; + /// Unique module prefix. E.g. "InstanceNMyModule" or "MyModule" + const PREFIX: &'static str ; } /// A trait similar to `Convert` to convert values from `B` an abstract balance type @@ -1779,6 +1779,53 @@ impl + UniqueSaturatedFrom> CurrencyToVote } } +/// Something that can be checked to be a of sub type `T`. +/// +/// This is useful for enums where each variant encapsulates a different sub type, and +/// you need access to these sub types. +/// +/// For example, in FRAME, this trait is implemented for the runtime `Call` enum. Pallets use this +/// to check if a certain call is an instance of the local pallet's `Call` enum. +/// +/// # Example +/// +/// ``` +/// # use frame_support::traits::IsSubType; +/// +/// enum Test { +/// String(String), +/// U32(u32), +/// } +/// +/// impl IsSubType for Test { +/// fn is_sub_type(&self) -> Option<&String> { +/// match self { +/// Self::String(ref r) => Some(r), +/// _ => None, +/// } +/// } +/// } +/// +/// impl IsSubType for Test { +/// fn is_sub_type(&self) -> Option<&u32> { +/// match self { +/// Self::U32(ref r) => Some(r), +/// _ => None, +/// } +/// } +/// } +/// +/// fn main() { +/// let data = Test::String("test".into()); +/// +/// assert_eq!("test", IsSubType::::is_sub_type(&data).unwrap().as_str()); +/// } +/// ``` +pub trait IsSubType { + /// Returns `Some(_)` if `self` is an instance of sub type `T`. + fn is_sub_type(&self) -> Option<&T>; +} + #[cfg(test)] mod tests { use super::*;