Move IsSubType and write some docs for the trait (#7350)

* Move `IsSubType` and write some docs for the trait

This moves the `IsSubType` trait from dispatch.rs to traits.rs. It also
adds docs to make the trait better understandable.

* Update frame/support/src/traits.rs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Bastian Köcher
2020-10-19 10:24:13 +02:00
committed by GitHub
parent 74e8691aa8
commit 87c18598fc
7 changed files with 58 additions and 16 deletions
+1 -5
View File
@@ -1900,10 +1900,6 @@ macro_rules! decl_module {
}
}
pub trait IsSubType<T> {
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 {
+2 -2
View File
@@ -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 {
+1 -1
View File
@@ -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.
+49 -2
View File
@@ -1708,8 +1708,8 @@ impl<T> IsType<T> 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<B: UniqueSaturatedInto<u64> + UniqueSaturatedFrom<u128>> CurrencyToVote<B>
}
}
/// 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<String> for Test {
/// fn is_sub_type(&self) -> Option<&String> {
/// match self {
/// Self::String(ref r) => Some(r),
/// _ => None,
/// }
/// }
/// }
///
/// impl IsSubType<u32> 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::<String>::is_sub_type(&data).unwrap().as_str());
/// }
/// ```
pub trait IsSubType<T> {
/// Returns `Some(_)` if `self` is an instance of sub type `T`.
fn is_sub_type(&self) -> Option<&T>;
}
#[cfg(test)]
mod tests {
use super::*;