mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 21:37:56 +00:00
Replace JSON metadata with custom metadata structures (#766)
* Move module metadata from json string to custom metadata * Revisit the metadata structures 1. Move the structures into the metadata crate. 2. Switch to using Cow/MaybeOwnedArray to support Encode/Decode * Adapt to new metadata structures * Convert event json metadata to new metadata structures * Convert storage json metadata to new metadata structures * Convert runtime metadata from json to new metadata structs * Implements new metadata structures in client and runtime * Fixes errors on `no_std` * Fixes errors after rebasing master * Do not use `Cow` anymore in metadata Also replace `String` with our own type definition `StringBuf`. This fixes compilation on `no_std`. * Wrap `RuntimeMetadata` in `RuntimeMetadataVersioned` to support versioning * Move metadata into `srml` and make core unaware of the implementation
This commit is contained in:
@@ -9,15 +9,14 @@ serde = { version = "1.0", default_features = false }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
parity-codec = { version = "1.1", default_features = false }
|
||||
substrate-primitives = { path = "../../core/primitives", default_features = false }
|
||||
substrate-metadata = { path = "../../core/metadata", default_features = false }
|
||||
substrate-metadata = { path = "../metadata", default_features = false }
|
||||
sr-std = { path = "../../core/sr-std", default_features = false }
|
||||
sr-io = { path = "../../core/sr-io", default_features = false }
|
||||
mashup = "0.1.7"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.5.1"
|
||||
serde_json = { version = "1.0" }
|
||||
parity-codec-derive = { version = "~1.0" }
|
||||
parity-codec-derive = { version = "1.0" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -23,6 +23,10 @@ pub use rstd::result;
|
||||
#[cfg(feature = "std")]
|
||||
use serde;
|
||||
pub use codec::{Codec, Decode, Encode, Input, Output};
|
||||
pub use substrate_metadata::{
|
||||
ModuleMetadata, FunctionMetadata, DecodeDifferent,
|
||||
CallMetadata, FunctionArgumentMetadata
|
||||
};
|
||||
|
||||
pub type Result = result::Result<(), &'static str>;
|
||||
|
||||
@@ -306,7 +310,7 @@ macro_rules! decl_module {
|
||||
d.dispatch(origin)
|
||||
}
|
||||
}
|
||||
__dispatch_impl_json_metadata! {
|
||||
__dispatch_impl_metadata! {
|
||||
$mod_type $trait_instance $trait_name $call_type $origin_type
|
||||
{$( $(#[doc = $doc_attr])* fn $fn_name($from $(, $param_name : $param )*) -> $result; )*}
|
||||
}
|
||||
@@ -461,15 +465,17 @@ macro_rules! __impl_outer_dispatch_common {
|
||||
/// Implement the `json_metadata` function.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __dispatch_impl_json_metadata {
|
||||
macro_rules! __dispatch_impl_metadata {
|
||||
(
|
||||
$mod_type:ident $trait_instance:ident $trait_name:ident
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
impl<$trait_instance: $trait_name> $mod_type<$trait_instance> {
|
||||
pub fn json_metadata() -> &'static str {
|
||||
concat!(r#"{ "name": ""#, stringify!($mod_type), r#"", "call": "#,
|
||||
__call_to_json!($($rest)*), " }")
|
||||
pub fn metadata() -> $crate::dispatch::ModuleMetadata {
|
||||
$crate::dispatch::ModuleMetadata {
|
||||
name: $crate::dispatch::DecodeDifferent::Encode(stringify!($mod_type)),
|
||||
call: __call_to_metadata!($($rest)*),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,7 +484,7 @@ macro_rules! __dispatch_impl_json_metadata {
|
||||
/// Convert the list of calls into their JSON representation, joined by ",".
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __call_to_json {
|
||||
macro_rules! __call_to_metadata {
|
||||
(
|
||||
$call_type:ident $origin_type:ty
|
||||
{$(
|
||||
@@ -490,111 +496,111 @@ macro_rules! __call_to_json {
|
||||
) -> $result:ty;
|
||||
)*}
|
||||
) => {
|
||||
concat!(
|
||||
r#"{ "name": ""#, stringify!($call_type),
|
||||
r#"", "functions": {"#,
|
||||
__functions_to_json!(""; 0; $origin_type; $(
|
||||
$crate::dispatch::CallMetadata {
|
||||
name: $crate::dispatch::DecodeDifferent::Encode(stringify!($call_type)),
|
||||
functions: __functions_to_metadata!(0; $origin_type;; $(
|
||||
fn $fn_name($from $(, $param_name: $param )* ) -> $result;
|
||||
__function_doc_to_json!(""; $($doc_attr)*);
|
||||
)*), " } }"
|
||||
)
|
||||
$( $doc_attr ),*;
|
||||
)*),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Convert a list of functions into their JSON representation, joined by ",".
|
||||
/// Convert a list of functions into a list of `FunctionMetadata` items.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __functions_to_json {
|
||||
macro_rules! __functions_to_metadata{
|
||||
// ROOT
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$fn_id:expr;
|
||||
$origin_type:ty;
|
||||
$( $function_metadata:expr ),*;
|
||||
fn $fn_name:ident(root
|
||||
$(
|
||||
, $param_name:ident : $param:ty
|
||||
)*
|
||||
) -> $result:ty;
|
||||
$fn_doc:expr;
|
||||
$($rest:tt)*
|
||||
$( $fn_doc:expr ),*;
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
concat!($prefix_str, " ",
|
||||
__function_to_json!(
|
||||
fn $fn_name(
|
||||
$( $param_name : $param ),*
|
||||
) -> $result;
|
||||
$fn_doc;
|
||||
$fn_id;
|
||||
), __functions_to_json!(","; $fn_id + 1; $origin_type; $($rest)*)
|
||||
)
|
||||
__functions_to_metadata!(
|
||||
$fn_id + 1; $origin_type;
|
||||
$( $function_metadata, )* __function_to_metadata!(
|
||||
fn $fn_name($( $param_name : $param ),*) -> $result; $( $fn_doc ),*; $fn_id;
|
||||
);
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
// NON ROOT
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$fn_id:expr;
|
||||
$origin_type:ty;
|
||||
$( $function_metadata:expr ),*;
|
||||
fn $fn_name:ident(origin
|
||||
$(
|
||||
, $param_name:ident : $param:ty
|
||||
)*
|
||||
) -> $result:ty;
|
||||
$fn_doc:expr;
|
||||
$( $fn_doc:expr ),*;
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
concat!($prefix_str, " ",
|
||||
__function_to_json!(
|
||||
fn $fn_name(
|
||||
origin: $origin_type
|
||||
$(, $param_name : $param)*
|
||||
) -> $result;
|
||||
$fn_doc;
|
||||
$fn_id;
|
||||
), __functions_to_json!(","; $fn_id + 1; $origin_type; $($rest)*)
|
||||
)
|
||||
__functions_to_metadata!(
|
||||
$fn_id + 1; $origin_type;
|
||||
$( $function_metadata, )* __function_to_metadata!(
|
||||
fn $fn_name(
|
||||
origin: $origin_type
|
||||
$( ,$param_name : $param )*
|
||||
) -> $result; $( $fn_doc ),*; $fn_id;
|
||||
);
|
||||
$($rest)*
|
||||
)
|
||||
};
|
||||
// BASE CASE
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$fn_id:expr;
|
||||
$($origin_type:ty;)*
|
||||
$origin_type:ty;
|
||||
$( $function_metadata:expr ),*;
|
||||
) => {
|
||||
""
|
||||
$crate::dispatch::DecodeDifferent::Encode(&[ $( $function_metadata ),* ])
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a function into its JSON representation.
|
||||
/// Convert a function into its metadata representation.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __function_to_json {
|
||||
macro_rules! __function_to_metadata {
|
||||
(
|
||||
fn $fn_name:ident(
|
||||
$first_param_name:ident : $first_param:ty $(, $param_name:ident : $param:ty)*
|
||||
$($param_name:ident : $param:ty),*
|
||||
) -> $result:ty;
|
||||
$fn_doc:tt;
|
||||
$( $fn_doc:expr ),*;
|
||||
$fn_id:expr;
|
||||
) => {
|
||||
concat!(
|
||||
r#"""#, stringify!($fn_id), r#"""#,
|
||||
r#": { "name": ""#, stringify!($fn_name),
|
||||
r#"", "params": [ "#,
|
||||
concat!(r#"{ "name": ""#, stringify!($first_param_name), r#"", "type": ""#, stringify!($first_param), r#"" }"# ),
|
||||
$crate::dispatch::FunctionMetadata {
|
||||
id: $fn_id,
|
||||
name: $crate::dispatch::DecodeDifferent::Encode(stringify!($fn_name)),
|
||||
arguments: $crate::dispatch::DecodeDifferent::Encode(&[
|
||||
$(
|
||||
concat!(r#", { "name": ""#, stringify!($param_name), r#"", "type": ""#, stringify!($param), r#"" }"# ),
|
||||
)*
|
||||
r#" ], "description": ["#, $fn_doc, " ] }"
|
||||
)
|
||||
$crate::dispatch::FunctionArgumentMetadata {
|
||||
name: $crate::dispatch::DecodeDifferent::Encode(stringify!($param_name)),
|
||||
ty: $crate::dispatch::DecodeDifferent::Encode(stringify!($param)),
|
||||
}
|
||||
),*
|
||||
]),
|
||||
documentation: $crate::dispatch::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]),
|
||||
}
|
||||
};
|
||||
(
|
||||
fn $fn_name:ident() -> $result:ty;
|
||||
$fn_doc:tt;
|
||||
$( $fn_doc:expr ),*;
|
||||
$fn_id:expr;
|
||||
) => {
|
||||
concat!(
|
||||
r#"""#, stringify!($fn_id), r#"""#,
|
||||
r#": { "name": ""#, stringify!($fn_name),
|
||||
r#"", "params": [ "#,
|
||||
r#" ], "description": ["#, $fn_doc, " ] }"
|
||||
)
|
||||
$crate::dispatch::FunctionMetadata {
|
||||
id: $fn_id,
|
||||
name: $crate::dispatch::DecodeDifferent::Encode(stringify!($fn_name)),
|
||||
arguments: $crate::dispatch::DecodeDifferent::Encode(&[]),
|
||||
documentation: $crate::dispatch::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -626,8 +632,6 @@ macro_rules! __function_doc_to_json {
|
||||
#[allow(dead_code)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde;
|
||||
use serde_json;
|
||||
|
||||
pub trait Trait {
|
||||
type Origin;
|
||||
@@ -652,33 +656,78 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
const EXPECTED_METADATA: &str = concat!(
|
||||
r#"{ "name": "Module", "call": "#,
|
||||
r#"{ "name": "Call", "functions": { "#,
|
||||
r#""0": { "name": "aux_0", "params": [ "#,
|
||||
r#"{ "name": "origin", "type": "T::Origin" }"#,
|
||||
r#" ], "description": [ " Hi, this is a comment." ] }, "#,
|
||||
|
||||
r#""0 + 1": { "name": "aux_1", "params": [ "#,
|
||||
r#"{ "name": "origin", "type": "T::Origin" }, "#,
|
||||
r#"{ "name": "data", "type": "i32" }"#,
|
||||
r#" ], "description": [ ] }, "#,
|
||||
|
||||
r#""0 + 1 + 1": { "name": "aux_2", "params": [ "#,
|
||||
r#"{ "name": "origin", "type": "T::Origin" }, "#,
|
||||
r#"{ "name": "data", "type": "i32" }, "#,
|
||||
r#"{ "name": "data2", "type": "String" }"#,
|
||||
r#" ], "description": [ ] }, "#,
|
||||
|
||||
r#""0 + 1 + 1 + 1": { "name": "aux_3", "params": [ "#,
|
||||
r#" ], "description": [ ] }, "#,
|
||||
|
||||
r#""0 + 1 + 1 + 1 + 1": { "name": "aux_4", "params": [ "#,
|
||||
r#"{ "name": "data", "type": "i32" }"#,
|
||||
r#" ], "description": [ ] }"#,
|
||||
r#" } }"#,
|
||||
r#" }"#,
|
||||
);
|
||||
const EXPECTED_METADATA: ModuleMetadata = ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module"),
|
||||
call: CallMetadata {
|
||||
name: DecodeDifferent::Encode("Call"),
|
||||
functions: DecodeDifferent::Encode(&[
|
||||
FunctionMetadata {
|
||||
id: 0,
|
||||
name: DecodeDifferent::Encode("aux_0"),
|
||||
arguments: DecodeDifferent::Encode(&[
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("origin"),
|
||||
ty: DecodeDifferent::Encode("T::Origin"),
|
||||
}
|
||||
]),
|
||||
documentation: DecodeDifferent::Encode(&[
|
||||
" Hi, this is a comment."
|
||||
])
|
||||
},
|
||||
FunctionMetadata {
|
||||
id: 1,
|
||||
name: DecodeDifferent::Encode("aux_1"),
|
||||
arguments: DecodeDifferent::Encode(&[
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("origin"),
|
||||
ty: DecodeDifferent::Encode("T::Origin"),
|
||||
},
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("data"),
|
||||
ty: DecodeDifferent::Encode("i32"),
|
||||
}
|
||||
]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
FunctionMetadata {
|
||||
id: 2,
|
||||
name: DecodeDifferent::Encode("aux_2"),
|
||||
arguments: DecodeDifferent::Encode(&[
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("origin"),
|
||||
ty: DecodeDifferent::Encode("T::Origin"),
|
||||
},
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("data"),
|
||||
ty: DecodeDifferent::Encode("i32"),
|
||||
},
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("data2"),
|
||||
ty: DecodeDifferent::Encode("String"),
|
||||
}
|
||||
]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
FunctionMetadata {
|
||||
id: 3,
|
||||
name: DecodeDifferent::Encode("aux_3"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
FunctionMetadata {
|
||||
id: 4,
|
||||
name: DecodeDifferent::Encode("aux_4"),
|
||||
arguments: DecodeDifferent::Encode(&[
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("data"),
|
||||
ty: DecodeDifferent::Encode("i32"),
|
||||
}
|
||||
]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
fn aux_0(_: T::Origin) -> Result {
|
||||
@@ -710,9 +759,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn module_json_metadata() {
|
||||
let metadata = Module::<TraitImpl>::json_metadata();
|
||||
let metadata = Module::<TraitImpl>::metadata();
|
||||
assert_eq!(EXPECTED_METADATA, metadata);
|
||||
let _: serde::de::IgnoredAny =
|
||||
serde_json::from_str(metadata).expect("Is valid json syntax");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
pub use substrate_metadata::{EventMetadata, DecodeDifferent, OuterEventMetadata, FnEncode};
|
||||
|
||||
/// Implement the `Event` for a module.
|
||||
///
|
||||
/// # Simple Event Example:
|
||||
@@ -125,8 +127,8 @@ macro_rules! decl_event {
|
||||
}
|
||||
impl Event {
|
||||
#[allow(dead_code)]
|
||||
pub fn event_json_metadata() -> &'static str {
|
||||
concat!("{", __events_to_json!(""; $( $events )* ), " }")
|
||||
pub fn metadata() -> &'static [ $crate::event::EventMetadata ] {
|
||||
__events_to_metadata!(; $( $events )* )
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,8 +228,8 @@ macro_rules! __decl_generic_event {
|
||||
}
|
||||
impl<$( $generic_param ),*> RawEvent<$( $generic_param ),*> {
|
||||
#[allow(dead_code)]
|
||||
pub fn event_json_metadata() -> &'static str {
|
||||
concat!("{", __events_to_json!(""; $( $events )* ), " }")
|
||||
pub fn metadata() -> &'static [$crate::event::EventMetadata] {
|
||||
__events_to_metadata!(; $( $events )* )
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,36 +237,31 @@ macro_rules! __decl_generic_event {
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __events_to_json {
|
||||
macro_rules! __events_to_metadata {
|
||||
(
|
||||
$prefix_str:expr;
|
||||
$( $metadata:expr ),*;
|
||||
$( #[doc = $doc_attr:tt] )*
|
||||
$event:ident( $first_param:path $(, $param:path )* ),
|
||||
$event:ident $( ( $( $param:path ),* ) )*,
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
concat!($prefix_str, " ", "\"", stringify!($event), r#"": { "params": [ ""#,
|
||||
stringify!($first_param), "\""
|
||||
$(, concat!(", \"", stringify!($param), "\"") )*, r#" ], "description": ["#,
|
||||
__function_doc_to_json!(""; $( $doc_attr )*), " ] }",
|
||||
__events_to_json!(","; $( $rest )*)
|
||||
__events_to_metadata!(
|
||||
$( $metadata, )*
|
||||
$crate::event::EventMetadata {
|
||||
name: $crate::event::DecodeDifferent::Encode(stringify!($event)),
|
||||
arguments: $crate::event::DecodeDifferent::Encode(&[
|
||||
$( $( stringify!($param) ),* )*
|
||||
]),
|
||||
documentation: $crate::event::DecodeDifferent::Encode(&[
|
||||
$( $doc_attr ),*
|
||||
]),
|
||||
};
|
||||
$( $rest )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:expr;
|
||||
$( #[doc = $doc_attr:tt] )*
|
||||
$event:ident,
|
||||
$( $rest:tt )*
|
||||
$( $metadata:expr ),*;
|
||||
) => {
|
||||
concat!($prefix_str, " ", "\"", stringify!($event),
|
||||
r#"": { "params": null, "description": ["#,
|
||||
__function_doc_to_json!(""; $( $doc_attr )*), " ] }",
|
||||
__events_to_json!(","; $( $rest )*)
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:expr;
|
||||
) => {
|
||||
""
|
||||
&[ $( $metadata ),* ]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,20 +405,21 @@ macro_rules! __impl_outer_event_json_metadata {
|
||||
) => {
|
||||
impl $runtime {
|
||||
#[allow(dead_code)]
|
||||
pub fn outer_event_json_metadata() -> (&'static str, &'static [(&'static str, fn() -> &'static str)]) {
|
||||
static METADATA: &[(&str, fn() -> &'static str)] = &[
|
||||
("system", $system::Event::event_json_metadata)
|
||||
$(
|
||||
, (
|
||||
stringify!($module_name),
|
||||
$module_name::Event $( ::<$generic_param> )*::event_json_metadata
|
||||
)
|
||||
)*
|
||||
];
|
||||
(
|
||||
stringify!($event_name),
|
||||
METADATA
|
||||
)
|
||||
pub fn outer_event_metadata() -> $crate::event::OuterEventMetadata {
|
||||
$crate::event::OuterEventMetadata {
|
||||
name: $crate::event::DecodeDifferent::Encode(stringify!($event_name)),
|
||||
events: $crate::event::DecodeDifferent::Encode(&[
|
||||
("system", $crate::event::FnEncode(system::Event::metadata))
|
||||
$(
|
||||
, (
|
||||
stringify!($module_name),
|
||||
$crate::event::FnEncode(
|
||||
$module_name::Event $( ::<$generic_param> )* ::metadata
|
||||
)
|
||||
)
|
||||
)*
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -430,8 +428,7 @@ macro_rules! __impl_outer_event_json_metadata {
|
||||
#[cfg(test)]
|
||||
#[allow(dead_code)]
|
||||
mod tests {
|
||||
use serde;
|
||||
use serde_json;
|
||||
use super::*;
|
||||
|
||||
mod system {
|
||||
pub trait Trait {
|
||||
@@ -567,46 +564,64 @@ mod tests {
|
||||
type Origin = u32;
|
||||
}
|
||||
|
||||
const EXPECTED_METADATA: (&str, &[(&str, &str)]) = (
|
||||
"TestEvent", &[
|
||||
("system", r#"{ "SystemEvent": { "params": null, "description": [ ] } }"#),
|
||||
("event_module",
|
||||
concat!(
|
||||
"{",
|
||||
r#" "TestEvent": { "params": [ "Balance", "Origin" ], "description": [ " Hi, I am a comment." ] },"#,
|
||||
r#" "EventWithoutParams": { "params": null, "description": [ " Dog" ] }"#,
|
||||
" }"
|
||||
)
|
||||
const EXPECTED_METADATA: OuterEventMetadata = OuterEventMetadata {
|
||||
name: DecodeDifferent::Encode("TestEvent"),
|
||||
events: DecodeDifferent::Encode(&[
|
||||
(
|
||||
"system",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("SystemEvent"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
])
|
||||
),
|
||||
("event_module2",
|
||||
concat!(
|
||||
"{",
|
||||
r#" "TestEvent": { "params": [ "BalanceRenamed" ], "description": [ ] },"#,
|
||||
r#" "TestOrigin": { "params": [ "OriginRenamed" ], "description": [ ] }"#,
|
||||
" }"
|
||||
)
|
||||
(
|
||||
"event_module",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("TestEvent"),
|
||||
arguments: DecodeDifferent::Encode(&[ "Balance", "Origin" ]),
|
||||
documentation: DecodeDifferent::Encode(&[ " Hi, I am a comment." ])
|
||||
},
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("EventWithoutParams"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[ " Dog" ]),
|
||||
},
|
||||
])
|
||||
),
|
||||
("event_module3",
|
||||
concat!(
|
||||
"{",
|
||||
r#" "HiEvent": { "params": null, "description": [ ] }"#,
|
||||
" }"
|
||||
)
|
||||
(
|
||||
"event_module2",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("TestEvent"),
|
||||
arguments: DecodeDifferent::Encode(&[ "BalanceRenamed" ]),
|
||||
documentation: DecodeDifferent::Encode(&[])
|
||||
},
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("TestOrigin"),
|
||||
arguments: DecodeDifferent::Encode(&[ "OriginRenamed" ]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
])
|
||||
),
|
||||
]
|
||||
);
|
||||
(
|
||||
"event_module3",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("HiEvent"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[])
|
||||
}
|
||||
])
|
||||
)
|
||||
])
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn outer_event_json_metadata() {
|
||||
let metadata = TestRuntime::outer_event_json_metadata();
|
||||
assert_eq!(EXPECTED_METADATA.0, metadata.0);
|
||||
assert_eq!(EXPECTED_METADATA.1.len(), metadata.1.len());
|
||||
|
||||
for (expected, got) in EXPECTED_METADATA.1.iter().zip(metadata.1.iter()) {
|
||||
assert_eq!(expected.0, got.0);
|
||||
assert_eq!(expected.1, got.1());
|
||||
let _: serde::de::IgnoredAny =
|
||||
serde_json::from_str(got.1()).expect(&format!("Is valid json syntax: {}", got.1()));
|
||||
}
|
||||
fn outer_event_metadata() {
|
||||
assert_eq!(EXPECTED_METADATA, TestRuntime::outer_event_metadata());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,6 @@ extern crate pretty_assertions;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[cfg(test)]
|
||||
extern crate serde_json;
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate parity_codec_derive;
|
||||
|
||||
@@ -62,7 +60,7 @@ pub mod dispatch;
|
||||
pub mod storage;
|
||||
mod hashable;
|
||||
#[macro_use]
|
||||
mod event;
|
||||
pub mod event;
|
||||
#[macro_use]
|
||||
pub mod metadata;
|
||||
#[macro_use]
|
||||
|
||||
@@ -14,38 +14,30 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use alloc;
|
||||
pub use substrate_metadata::JsonMetadata;
|
||||
pub use substrate_metadata::{
|
||||
DecodeDifferent, FnEncode, RuntimeMetadata, RuntimeModuleMetadata
|
||||
};
|
||||
|
||||
/// Make Box available on `std` and `no_std`.
|
||||
pub type Box<T> = alloc::boxed::Box<T>;
|
||||
/// Make Vec available on `std` and `no_std`.
|
||||
pub type Vec<T> = alloc::vec::Vec<T>;
|
||||
|
||||
/// Implements the json metadata support for the given runtime and all its modules.
|
||||
/// Implements the metadata support for the given runtime and all its modules.
|
||||
///
|
||||
/// Example:
|
||||
/// ```compile_fail
|
||||
/// impl_json_metadata!(for RUNTIME_NAME with modules MODULE0, MODULE2, MODULE3 with Storage);
|
||||
/// 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_json_metadata {
|
||||
macro_rules! impl_runtime_metadata {
|
||||
(
|
||||
for $runtime:ident with modules
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
impl $runtime {
|
||||
pub fn json_metadata() -> $crate::metadata::Vec<$crate::metadata::JsonMetadata> {
|
||||
let events = Self::outer_event_json_metadata();
|
||||
__impl_json_metadata!($runtime;
|
||||
$crate::metadata::JsonMetadata::Events {
|
||||
name: events.0,
|
||||
events: events.1,
|
||||
};
|
||||
$( $rest )*
|
||||
)
|
||||
pub fn metadata() -> $crate::metadata::RuntimeMetadata {
|
||||
$crate::metadata::RuntimeMetadata {
|
||||
outer_event: Self::outer_event_metadata(),
|
||||
modules: __runtime_modules_to_metadata!($runtime;; $( $rest )*),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,66 +45,50 @@ macro_rules! impl_json_metadata {
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __impl_json_metadata {
|
||||
macro_rules! __runtime_modules_to_metadata {
|
||||
(
|
||||
$runtime: ident;
|
||||
$( $metadata:expr ),*;
|
||||
$mod:ident::$module:ident,
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
__impl_json_metadata!(
|
||||
__runtime_modules_to_metadata!(
|
||||
$runtime;
|
||||
$( $metadata, )* $crate::metadata::JsonMetadata::Module {
|
||||
module: $mod::$module::<$runtime>::json_metadata(), prefix: stringify!($mod)
|
||||
$( $metadata, )* $crate::metadata::RuntimeModuleMetadata {
|
||||
prefix: $crate::metadata::DecodeDifferent::Encode(stringify!($mod)),
|
||||
module: $crate::metadata::DecodeDifferent::Encode(
|
||||
$crate::metadata::FnEncode($mod::$module::<$runtime>::metadata)
|
||||
),
|
||||
storage: None,
|
||||
};
|
||||
$( $rest )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$runtime: ident;
|
||||
$( $metadata:expr ),*;
|
||||
$mod:ident::$module:ident
|
||||
) => {
|
||||
__impl_json_metadata!(
|
||||
$runtime;
|
||||
$( $metadata, )* $crate::metadata::JsonMetadata::Module {
|
||||
module: $mod::$module::<$runtime>::json_metadata(), prefix: stringify!($mod)
|
||||
};
|
||||
)
|
||||
};
|
||||
(
|
||||
$runtime: ident;
|
||||
$( $metadata:expr ),*;
|
||||
$mod:ident::$module:ident with Storage,
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
__impl_json_metadata!(
|
||||
__runtime_modules_to_metadata!(
|
||||
$runtime;
|
||||
$( $metadata, )* $crate::metadata::JsonMetadata::ModuleWithStorage {
|
||||
module: $mod::$module::<$runtime>::json_metadata(), prefix: stringify!($mod),
|
||||
storage: $mod::$module::<$runtime>::store_json_metadata()
|
||||
$( $metadata, )* $crate::metadata::RuntimeModuleMetadata {
|
||||
prefix: $crate::metadata::DecodeDifferent::Encode(stringify!($mod)),
|
||||
module: $crate::metadata::DecodeDifferent::Encode(
|
||||
$crate::metadata::FnEncode($mod::$module::<$runtime>::metadata)
|
||||
),
|
||||
storage: Some($crate::metadata::DecodeDifferent::Encode(
|
||||
$crate::metadata::FnEncode($mod::$module::<$runtime>::store_metadata)
|
||||
)),
|
||||
};
|
||||
$( $rest )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$runtime: ident;
|
||||
$( $metadata:expr ),*;
|
||||
$mod:ident::$module:ident with Storage
|
||||
) => {
|
||||
__impl_json_metadata!(
|
||||
$runtime;
|
||||
$( $metadata, )* $crate::metadata::JsonMetadata::ModuleWithStorage {
|
||||
module: $mod::$module::<$runtime>::json_metadata(), prefix: stringify!($mod),
|
||||
storage: $mod::$module::<$runtime>::store_json_metadata()
|
||||
};
|
||||
)
|
||||
};
|
||||
(
|
||||
$runtime:ident;
|
||||
$( $metadata:expr ),*;
|
||||
) => {
|
||||
<[_]>::into_vec($crate::metadata::Box::new([ $( $metadata ),* ]))
|
||||
$crate::metadata::DecodeDifferent::Encode(&[ $( $metadata ),* ])
|
||||
};
|
||||
}
|
||||
|
||||
@@ -121,9 +97,11 @@ macro_rules! __impl_json_metadata {
|
||||
#[allow(dead_code)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde;
|
||||
use serde_json;
|
||||
use substrate_metadata::JsonMetadataDecodable;
|
||||
use substrate_metadata::{
|
||||
EventMetadata, OuterEventMetadata, RuntimeModuleMetadata, CallMetadata, ModuleMetadata,
|
||||
StorageFunctionModifier, StorageFunctionType, FunctionMetadata, FunctionArgumentMetadata,
|
||||
StorageMetadata, StorageFunctionMetadata,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
|
||||
mod system {
|
||||
@@ -219,79 +197,110 @@ mod tests {
|
||||
type Origin = u32;
|
||||
}
|
||||
|
||||
fn system_event_json() -> &'static str {
|
||||
r#"{ "SystemEvent": { "params": null, "description": [ ] } }"#
|
||||
}
|
||||
|
||||
fn event_module_event_json() -> &'static str {
|
||||
r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ " Hi, I am a comment." ] } }"#
|
||||
}
|
||||
|
||||
fn event_module2_event_json() -> &'static str {
|
||||
r#"{ "TestEvent": { "params": [ "Balance" ], "description": [ ] } }"#
|
||||
}
|
||||
|
||||
impl_json_metadata!(
|
||||
impl_runtime_metadata!(
|
||||
for TestRuntime with modules
|
||||
event_module::Module,
|
||||
event_module2::ModuleWithStorage with Storage
|
||||
event_module2::ModuleWithStorage with Storage,
|
||||
);
|
||||
|
||||
const EXPECTED_METADATA: &[JsonMetadata] = &[
|
||||
JsonMetadata::Events {
|
||||
name: "TestEvent",
|
||||
events: &[
|
||||
("system", system_event_json),
|
||||
("event_module", event_module_event_json),
|
||||
("event_module2", event_module2_event_json),
|
||||
]
|
||||
const EXPECTED_METADATA: RuntimeMetadata = RuntimeMetadata {
|
||||
outer_event: OuterEventMetadata {
|
||||
name: DecodeDifferent::Encode("TestEvent"),
|
||||
events: DecodeDifferent::Encode(&[
|
||||
(
|
||||
"system",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("SystemEvent"),
|
||||
arguments: DecodeDifferent::Encode(&[]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
])
|
||||
),
|
||||
(
|
||||
"event_module",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("TestEvent"),
|
||||
arguments: DecodeDifferent::Encode(&["Balance"]),
|
||||
documentation: DecodeDifferent::Encode(&[" Hi, I am a comment."])
|
||||
}
|
||||
])
|
||||
),
|
||||
(
|
||||
"event_module2",
|
||||
FnEncode(|| &[
|
||||
EventMetadata {
|
||||
name: DecodeDifferent::Encode("TestEvent"),
|
||||
arguments: DecodeDifferent::Encode(&["Balance"]),
|
||||
documentation: DecodeDifferent::Encode(&[])
|
||||
}
|
||||
])
|
||||
)
|
||||
]),
|
||||
},
|
||||
JsonMetadata::Module {
|
||||
module: concat!(
|
||||
r#"{ "name": "Module", "call": "#,
|
||||
r#"{ "name": "Call", "functions": "#,
|
||||
r#"{ "0": { "name": "aux_0", "params": [ "#,
|
||||
r#"{ "name": "origin", "type": "T::Origin" } ], "#,
|
||||
r#""description": [ ] } } } }"#
|
||||
),
|
||||
prefix: "event_module"
|
||||
},
|
||||
JsonMetadata::ModuleWithStorage {
|
||||
module: r#"{ "name": "ModuleWithStorage", "call": { "name": "Call", "functions": { } } }"#,
|
||||
prefix: "event_module2",
|
||||
storage: concat!(
|
||||
r#"{ "prefix": "TestStorage", "items": { "#,
|
||||
r#""StorageMethod": { "description": [ ], "modifier": null, "type": "u32" }"#,
|
||||
r#" } }"#
|
||||
)
|
||||
}
|
||||
];
|
||||
modules: DecodeDifferent::Encode(&[
|
||||
RuntimeModuleMetadata {
|
||||
prefix: DecodeDifferent::Encode("event_module"),
|
||||
module: DecodeDifferent::Encode(FnEncode(||
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("Module"),
|
||||
call: CallMetadata {
|
||||
name: DecodeDifferent::Encode("Call"),
|
||||
functions: DecodeDifferent::Encode(&[
|
||||
FunctionMetadata {
|
||||
id: 0,
|
||||
name: DecodeDifferent::Encode("aux_0"),
|
||||
arguments: DecodeDifferent::Encode(&[
|
||||
FunctionArgumentMetadata {
|
||||
name: DecodeDifferent::Encode("origin"),
|
||||
ty: DecodeDifferent::Encode("T::Origin"),
|
||||
}
|
||||
]),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
])
|
||||
}
|
||||
}
|
||||
)),
|
||||
storage: None,
|
||||
},
|
||||
RuntimeModuleMetadata {
|
||||
prefix: DecodeDifferent::Encode("event_module2"),
|
||||
module: DecodeDifferent::Encode(FnEncode(||
|
||||
ModuleMetadata {
|
||||
name: DecodeDifferent::Encode("ModuleWithStorage"),
|
||||
call: CallMetadata {
|
||||
name: DecodeDifferent::Encode("Call"),
|
||||
functions: DecodeDifferent::Encode(&[])
|
||||
}
|
||||
}
|
||||
)),
|
||||
storage: Some(DecodeDifferent::Encode(FnEncode(||
|
||||
StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("TestStorage"),
|
||||
functions: DecodeDifferent::Encode(&[
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("StorageMethod"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
])
|
||||
}
|
||||
))),
|
||||
}
|
||||
])
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn runtime_json_metadata() {
|
||||
let metadata = TestRuntime::json_metadata();
|
||||
assert_eq!(EXPECTED_METADATA, &metadata[..]);
|
||||
}
|
||||
fn runtime_metadata() {
|
||||
let metadata = TestRuntime::metadata();
|
||||
assert_eq!(EXPECTED_METADATA, metadata);
|
||||
|
||||
#[test]
|
||||
fn json_metadata_encode_and_decode() {
|
||||
let metadata = TestRuntime::json_metadata();
|
||||
let metadata_encoded = metadata.encode();
|
||||
let metadata_decoded = Vec::<JsonMetadataDecodable>::decode(&mut &metadata_encoded[..]);
|
||||
let metadata_decoded = RuntimeMetadata::decode(&mut &metadata_encoded[..]);
|
||||
|
||||
assert_eq!(&metadata_decoded.unwrap()[..], &metadata[..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn into_json_string_is_valid_json() {
|
||||
let metadata = TestRuntime::json_metadata();
|
||||
let metadata_encoded = metadata.encode();
|
||||
let metadata_decoded = Vec::<JsonMetadataDecodable>::decode(&mut &metadata_encoded[..]);
|
||||
|
||||
for mdata in metadata_decoded.unwrap().into_iter() {
|
||||
let json = mdata.into_json_string();
|
||||
let _: serde::de::IgnoredAny =
|
||||
serde_json::from_str(&json.1).expect(&format!("Is valid json syntax: {}", json.1));
|
||||
}
|
||||
assert_eq!(metadata, metadata_decoded.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ macro_rules! construct_runtime {
|
||||
$name: $module::{ $( $modules $( <$modules_generic> )* ),* }
|
||||
),*;
|
||||
);
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
;
|
||||
;
|
||||
@@ -664,7 +664,7 @@ macro_rules! __decl_outer_dispatch {
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __decl_json_metadata {
|
||||
macro_rules! __decl_runtime_metadata {
|
||||
(
|
||||
$runtime:ident;
|
||||
;
|
||||
@@ -676,7 +676,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
$module { Module, };
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* } ),*;
|
||||
@@ -699,7 +699,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
;
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* }, )* $module { Module with Storage };
|
||||
@@ -721,7 +721,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
$module { , Storage };
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* } ),*;
|
||||
@@ -744,7 +744,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
;
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* }, )* $module { Module with Storage };
|
||||
@@ -766,7 +766,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
$( $current_module { $( $current_module_storage )* } )*;
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* } ),*;
|
||||
@@ -787,7 +787,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
;
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* }, )* $module { Module };
|
||||
@@ -807,7 +807,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $rest_modules:ident $( <$rest_modules_generic:ident> )* ),*
|
||||
})*;
|
||||
) => {
|
||||
__decl_json_metadata!(
|
||||
__decl_runtime_metadata!(
|
||||
$runtime;
|
||||
;
|
||||
$( $parsed_modules { Module $( with $parsed_storage )* } ),*;
|
||||
@@ -824,7 +824,7 @@ macro_rules! __decl_json_metadata {
|
||||
$( $parsed_modules:ident { Module $( with $parsed_storage:ident )* } ),*;
|
||||
;
|
||||
) => {
|
||||
impl_json_metadata!(
|
||||
impl_runtime_metadata!(
|
||||
for $runtime with modules
|
||||
$( $parsed_modules::Module $(with $parsed_storage)*, )*
|
||||
);
|
||||
|
||||
@@ -53,6 +53,11 @@ pub use rstd::borrow::Borrow;
|
||||
#[doc(hidden)]
|
||||
pub use rstd::marker::PhantomData;
|
||||
|
||||
pub use substrate_metadata::{
|
||||
DecodeDifferent, StorageMetadata, StorageFunctionMetadata,
|
||||
StorageFunctionType, StorageFunctionModifier
|
||||
};
|
||||
|
||||
/// Abstraction around storage.
|
||||
pub trait Storage {
|
||||
/// true if the key exists in storage.
|
||||
@@ -530,7 +535,7 @@ macro_rules! decl_storage {
|
||||
}
|
||||
impl<$traitinstance: $traittype> $modulename<$traitinstance> {
|
||||
__impl_store_fns!($traitinstance $($t)*);
|
||||
__impl_store_json_metadata!($cratename; $($t)*);
|
||||
__impl_store_metadata!($cratename; $($t)*);
|
||||
}
|
||||
};
|
||||
(
|
||||
@@ -1080,390 +1085,427 @@ macro_rules! __impl_store_item {
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __impl_store_json_metadata {
|
||||
macro_rules! __impl_store_metadata {
|
||||
(
|
||||
$cratename:ident;
|
||||
$($rest:tt)*
|
||||
) => {
|
||||
pub fn store_json_metadata() -> &'static str {
|
||||
concat!(r#"{ "prefix": ""#, stringify!($cratename), r#"", "items": {"#,
|
||||
__store_functions_to_json!(""; $($rest)*), " } }")
|
||||
pub fn store_metadata() -> $crate::storage::generator::StorageMetadata {
|
||||
$crate::storage::generator::StorageMetadata {
|
||||
prefix: $crate::storage::generator::DecodeDifferent::Encode(stringify!($cratename)),
|
||||
functions: __store_functions_to_metadata!(; $( $rest )* ),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __store_functions_to_json {
|
||||
macro_rules! __store_functions_to_metadata {
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident :
|
||||
default $ty:ty; $($t:tt)*
|
||||
$name:ident : default $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident :
|
||||
default $ty:ty; $($t:tt)*
|
||||
pub $name:ident : default $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident :
|
||||
required $ty:ty; $($t:tt)*
|
||||
$name:ident : required $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident :
|
||||
required $ty:ty; $($t:tt)*
|
||||
pub $name:ident : required $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
// simple values
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident :
|
||||
$ty:ty; $($t:tt)*
|
||||
$name:ident : $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty)
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident :
|
||||
$ty:ty; $($t:tt)*
|
||||
pub $name:ident : $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty)
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident get($getfn:ident) :
|
||||
default $ty:ty; $($t:tt)*
|
||||
default $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident get($getfn:ident) :
|
||||
default $ty:ty; $($t:tt)*
|
||||
default $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident get($getfn:ident) :
|
||||
required $ty:ty; $($t:tt)*
|
||||
required $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident get($getfn:ident) :
|
||||
required $ty:ty; $($t:tt)*
|
||||
required $ty:ty;
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident get($getfn:ident) :
|
||||
$ty:ty; $($t:tt)*
|
||||
$name:ident get($getfn:ident) : $ty:ty;
|
||||
$( $t:tt )*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty)
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident get($getfn:ident) :
|
||||
$ty:ty; $($t:tt)*
|
||||
pub $name:ident get($getfn:ident) : $ty:ty;
|
||||
$( $t:tt )*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($ty)
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
|
||||
// maps
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident :
|
||||
default map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
default map [$kty:ty => $ty:ty];
|
||||
$( $t:tt )*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident :
|
||||
default map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
default map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident :
|
||||
required map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
required map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident :
|
||||
required map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
required map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident :
|
||||
map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty)
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident :
|
||||
map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty)
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])* $name:ident get($getfn:ident) :
|
||||
default map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
default map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident get($getfn:ident) :
|
||||
default map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
default map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), default
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), default
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])* $name:ident get($getfn:ident) :
|
||||
required map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
required map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), required
|
||||
);
|
||||
$( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident get($getfn:ident) :
|
||||
required map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
required map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty), required
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty), required
|
||||
); $( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
$name:ident get($getfn:ident) :
|
||||
map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty)
|
||||
); $( $t )*
|
||||
)
|
||||
};
|
||||
(
|
||||
$prefix_str:tt;
|
||||
$( $metadata:expr ),*;
|
||||
$(#[doc = $doc_attr:tt])*
|
||||
pub $name:ident get($getfn:ident) :
|
||||
map [$kty:ty => $ty:ty]; $($t:tt)*
|
||||
map [$kty:ty => $ty:ty];
|
||||
$($t:tt)*
|
||||
) => {
|
||||
concat!(
|
||||
__store_function_to_json!($prefix_str,
|
||||
__function_doc_to_json!(""; $($doc_attr)*),
|
||||
$name, __store_type_to_json!($kty, $ty)
|
||||
),
|
||||
__store_functions_to_json!(","; $($t)*)
|
||||
__store_functions_to_metadata!(
|
||||
$( $metadata, )*
|
||||
__store_function_to_metadata!(
|
||||
$( $doc_attr ),*; $name, __store_type_to_metadata!($kty, $ty)
|
||||
); $( $t )*
|
||||
)
|
||||
};
|
||||
($prefix_str:tt;) => { "" }
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __store_function_to_json {
|
||||
($prefix_str:tt, $fn_doc:expr, $name:ident, $type:expr, $modifier:ident) => {
|
||||
__store_function_to_json!($prefix_str; $fn_doc; $name; $type;
|
||||
concat!("\"", stringify!($modifier), "\""))
|
||||
};
|
||||
($prefix_str:tt, $fn_doc:expr, $name:ident, $type:expr) => {
|
||||
__store_function_to_json!($prefix_str; $fn_doc; $name; $type; "null")
|
||||
};
|
||||
($prefix_str:tt; $fn_doc:expr; $name:ident; $type:expr; $modifier:expr) => {
|
||||
concat!($prefix_str, " \"", stringify!($name), "\": { ",
|
||||
r#""description": ["#, $fn_doc, " ], ",
|
||||
r#""modifier": "#, $modifier, r#", "type": "#, $type, r#" }"#
|
||||
)
|
||||
(
|
||||
$( $metadata:expr ),*;
|
||||
) => {
|
||||
$crate::storage::generator::DecodeDifferent::Encode(&[
|
||||
$( $metadata ),*
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __store_type_to_json {
|
||||
macro_rules! __store_function_to_metadata {
|
||||
($( $fn_doc:expr ),*; $name:ident, $type:expr, required) => {
|
||||
__store_function_to_metadata!(
|
||||
$( $fn_doc ),*; $name; $type;
|
||||
$crate::storage::generator::StorageFunctionModifier::Required
|
||||
)
|
||||
};
|
||||
($( $fn_doc:expr ),*; $name:ident, $type:expr, default) => {
|
||||
__store_function_to_metadata!(
|
||||
$( $fn_doc ),*; $name; $type;
|
||||
$crate::storage::generator::StorageFunctionModifier::Default
|
||||
)
|
||||
};
|
||||
($( $fn_doc:expr ),*; $name:ident, $type:expr) => {
|
||||
__store_function_to_metadata!(
|
||||
$( $fn_doc ),*; $name; $type;
|
||||
$crate::storage::generator::StorageFunctionModifier::None
|
||||
)
|
||||
};
|
||||
($( $fn_doc:expr ),*; $name:ident; $type:expr; $modifier:expr) => {
|
||||
$crate::storage::generator::StorageFunctionMetadata {
|
||||
name: $crate::storage::generator::DecodeDifferent::Encode(stringify!($name)),
|
||||
modifier: $modifier,
|
||||
ty: $type,
|
||||
documentation: $crate::storage::generator::DecodeDifferent::Encode(&[ $( $fn_doc ),* ]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __store_type_to_metadata {
|
||||
($name:ty) => {
|
||||
concat!("\"", stringify!($name), "\"")
|
||||
$crate::storage::generator::StorageFunctionType::Plain(
|
||||
$crate::storage::generator::DecodeDifferent::Encode(stringify!($name)),
|
||||
)
|
||||
};
|
||||
($key: ty, $value:ty) => {
|
||||
concat!(r#"{ "key": ""#, stringify!($key), r#"", "value": ""#,
|
||||
stringify!($value), "\" }")
|
||||
$crate::storage::generator::StorageFunctionType::Map {
|
||||
key: $crate::storage::generator::DecodeDifferent::Encode(stringify!($key)),
|
||||
value: $crate::storage::generator::DecodeDifferent::Encode(stringify!($value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1475,8 +1517,6 @@ mod tests {
|
||||
use std::cell::RefCell;
|
||||
use codec::Codec;
|
||||
use super::*;
|
||||
use serde;
|
||||
use serde_json;
|
||||
|
||||
impl Storage for RefCell<HashMap<Vec<u8>, Vec<u8>>> {
|
||||
fn exists(&self, key: &[u8]) -> bool {
|
||||
@@ -1580,7 +1620,6 @@ mod tests {
|
||||
GETMAPU32Required get(map_get_u32_required): required map [ u32 => String ];
|
||||
pub PUBMAPU32Required : required map [ u32 => String ];
|
||||
pub GETPUBMAPU32Required get(map_pub_get_u32_required): required map [ u32 => String ];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1590,41 +1629,186 @@ mod tests {
|
||||
type Origin = u32;
|
||||
}
|
||||
|
||||
const EXPECTED_METADATA: &str = concat!(
|
||||
r#"{ "prefix": "TestStorage", "items": { "#,
|
||||
r#""U32": { "description": [ " Hello, this is doc!" ], "modifier": null, "type": "u32" }, "#,
|
||||
r#""GETU32": { "description": [ ], "modifier": null, "type": "u32" }, "#,
|
||||
r#""PUBU32": { "description": [ ], "modifier": null, "type": "u32" }, "#,
|
||||
r#""GETPUBU32": { "description": [ ], "modifier": null, "type": "u32" }, "#,
|
||||
r#""U32Default": { "description": [ ], "modifier": "default", "type": "u32" }, "#,
|
||||
r#""GETU32Default": { "description": [ ], "modifier": "default", "type": "u32" }, "#,
|
||||
r#""PUBU32Default": { "description": [ ], "modifier": "default", "type": "u32" }, "#,
|
||||
r#""GETPUBU32Default": { "description": [ ], "modifier": "default", "type": "u32" }, "#,
|
||||
r#""U32Required": { "description": [ ], "modifier": "required", "type": "u32" }, "#,
|
||||
r#""GETU32Required": { "description": [ ], "modifier": "required", "type": "u32" }, "#,
|
||||
r#""PUBU32Required": { "description": [ ], "modifier": "required", "type": "u32" }, "#,
|
||||
r#""GETPUBU32Required": { "description": [ ], "modifier": "required", "type": "u32" }, "#,
|
||||
r#""MAPU32": { "description": [ ], "modifier": null, "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""GETMAPU32": { "description": [ " Hello, this is doc!", " Hello, this is doc 2!" ], "modifier": null, "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""PUBMAPU32": { "description": [ ], "modifier": null, "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""GETPUBMAPU32": { "description": [ ], "modifier": null, "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""MAPU32Default": { "description": [ ], "modifier": "default", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""GETMAPU32Default": { "description": [ ], "modifier": "default", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""PUBMAPU32Default": { "description": [ ], "modifier": "default", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""GETPUBMAPU32Default": { "description": [ ], "modifier": "default", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""MAPU32Required": { "description": [ ], "modifier": "required", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""GETMAPU32Required": { "description": [ ], "modifier": "required", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""PUBMAPU32Required": { "description": [ ], "modifier": "required", "type": { "key": "u32", "value": "String" } }, "#,
|
||||
r#""GETPUBMAPU32Required": { "description": [ ], "modifier": "required", "type": { "key": "u32", "value": "String" } }"#,
|
||||
" } }"
|
||||
);
|
||||
const EXPECTED_METADATA: StorageMetadata = StorageMetadata {
|
||||
prefix: DecodeDifferent::Encode("TestStorage"),
|
||||
functions: DecodeDifferent::Encode(&[
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("U32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[ " Hello, this is doc!" ]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("PUBU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETPUBU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("U32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("PUBU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETPUBU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("U32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("PUBU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETPUBU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Plain(DecodeDifferent::Encode("u32")),
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("MAPU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETMAPU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[
|
||||
" Hello, this is doc!", " Hello, this is doc 2!"
|
||||
]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("PUBMAPU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETPUBMAPU32"),
|
||||
modifier: StorageFunctionModifier::None,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("MAPU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETMAPU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("PUBMAPU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETPUBMAPU32Default"),
|
||||
modifier: StorageFunctionModifier::Default,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("MAPU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETMAPU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("PUBMAPU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
},
|
||||
StorageFunctionMetadata {
|
||||
name: DecodeDifferent::Encode("GETPUBMAPU32Required"),
|
||||
modifier: StorageFunctionModifier::Required,
|
||||
ty: StorageFunctionType::Map{
|
||||
key: DecodeDifferent::Encode("u32"), value: DecodeDifferent::Encode("String")
|
||||
},
|
||||
documentation: DecodeDifferent::Encode(&[]),
|
||||
}
|
||||
])
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn store_json_metadata() {
|
||||
let metadata = Module::<TraitImpl>::store_json_metadata();
|
||||
fn store_metadata() {
|
||||
let metadata = Module::<TraitImpl>::store_metadata();
|
||||
assert_eq!(EXPECTED_METADATA, metadata);
|
||||
let _: serde::de::IgnoredAny =
|
||||
serde_json::from_str(metadata).expect("Is valid json syntax");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user