// Copyright 2018-2019 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Substrate is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
pub use srml_metadata::{
DecodeDifferent, FnEncode, RuntimeMetadata,
ModuleMetadata, RuntimeMetadataV4,
DefaultByteGetter, RuntimeMetadataPrefixed,
StorageMetadata, StorageFunctionMetadata,
StorageFunctionType, StorageFunctionModifier,
DefaultByte, StorageHasher
};
/// Implements the metadata support for the given runtime and all its modules.
///
/// Example:
/// ```compile_fail
/// impl_runtime_metadata!(for RUNTIME_NAME with modules MODULE0, MODULE2, MODULE3 with Storage);
/// ```
///
/// In this example, just `MODULE3` implements the `Storage` trait.
#[macro_export]
macro_rules! impl_runtime_metadata {
(
for $runtime:ident with modules
$( $rest:tt )*
) => {
impl $runtime {
pub fn metadata() -> $crate::metadata::RuntimeMetadataPrefixed {
$crate::metadata::RuntimeMetadata::V4 (
$crate::metadata::RuntimeMetadataV4 {
modules: $crate::__runtime_modules_to_metadata!($runtime;; $( $rest )*),
}
).into()
}
}
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! __runtime_modules_to_metadata {
(
$runtime: ident;
$( $metadata:expr ),*;
$mod:ident::$module:ident $( < $instance:ident > )? $(with)+ $($kw:ident)*,
$( $rest:tt )*
) => {
$crate::__runtime_modules_to_metadata!(
$runtime;
$( $metadata, )* $crate::metadata::ModuleMetadata {
name: $crate::metadata::DecodeDifferent::Encode(stringify!($mod)),
prefix: $crate::__runtime_modules_to_metadata_calls_storagename!($mod, $module $( <$instance> )?, $runtime, $(with $kw)*),
storage: $crate::__runtime_modules_to_metadata_calls_storage!($mod, $module $( <$instance> )?, $runtime, $(with $kw)*),
calls: $crate::__runtime_modules_to_metadata_calls_call!($mod, $module $( <$instance> )?, $runtime, $(with $kw)*),
event: $crate::__runtime_modules_to_metadata_calls_event!($mod, $module $( <$instance> )?, $runtime, $(with $kw)*),
};
$( $rest )*
)
};
(
$runtime:ident;
$( $metadata:expr ),*;
) => {
$crate::metadata::DecodeDifferent::Encode(&[ $( $metadata ),* ])
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __runtime_modules_to_metadata_calls_call {
// skip system
(
system,
$skip_module: ident $( <$instance:ident> )?,
$skip_runtime: ident,
with Call
$(with $kws:ident)*
) => {
None
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with Call
$(with $kws:ident)*
) => {
Some($crate::metadata::DecodeDifferent::Encode(
$crate::metadata::FnEncode(
$mod::$module::<$runtime $(, $mod::$instance )?>::call_functions
)
))
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with $_:ident
$(with $kws:ident)*
) => {
$crate::__runtime_modules_to_metadata_calls_call!( $mod, $module $( <$instance> )?, $runtime, $(with $kws)* );
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
) => {
None
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __runtime_modules_to_metadata_calls_event {
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with Event
$(with $kws:ident)*
) => {
Some($crate::metadata::DecodeDifferent::Encode(
$crate::metadata::FnEncode(
$crate::paste::expr!{
$runtime:: [< __module_events_ $mod $(_ $instance)?>]
}
)
))
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with $_:ident
$(with $kws:ident)*
) => {
$crate::__runtime_modules_to_metadata_calls_event!( $mod, $module $( <$instance> )?, $runtime, $(with $kws)* );
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
) => {
None
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __runtime_modules_to_metadata_calls_storagename {
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with Storage
$(with $kws:ident)*
) => {
$crate::metadata::DecodeDifferent::Encode(
$crate::metadata::FnEncode(
$mod::$module::<$runtime $(, $mod::$instance )?>::store_metadata_name
)
)
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with $_:ident
$(with $kws:ident)*
) => {
$crate::__runtime_modules_to_metadata_calls_storagename!( $mod, $module $( <$instance> )?, $runtime, $(with $kws)* );
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
) => {
$crate::metadata::DecodeDifferent::Encode(
$crate::metadata::FnEncode(|| "")
)
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __runtime_modules_to_metadata_calls_storage {
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with Storage
$(with $kws:ident)*
) => {
Some($crate::metadata::DecodeDifferent::Encode(
$crate::metadata::FnEncode(
$mod::$module::<$runtime $(, $mod::$instance )?>::store_metadata_functions
)
))
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
with $_:ident
$(with $kws:ident)*
) => {
$crate::__runtime_modules_to_metadata_calls_storage!( $mod, $module $( <$instance> )?, $runtime, $(with $kws)* );
};
(
$mod: ident,
$module: ident $( <$instance:ident> )?,
$runtime: ident,
) => {
None
};
}
#[cfg(test)]
// Do not complain about unused `dispatch` and `dispatch_aux`.
#[allow(dead_code)]
mod tests {
use super::*;
use srml_metadata::{
EventMetadata,
StorageFunctionModifier, StorageFunctionType, FunctionMetadata,
StorageFunctionMetadata,
ModuleMetadata, RuntimeMetadataPrefixed
};
use crate::codec::{Encode, Decode};
mod system {
pub trait Trait {
type Origin: Into