diff --git a/substrate/runtime-support/src/dispatch.rs b/substrate/runtime-support/src/dispatch.rs index 7ef9c7cf1c019..903cf9ae04f81 100644 --- a/substrate/runtime-support/src/dispatch.rs +++ b/substrate/runtime-support/src/dispatch.rs @@ -150,6 +150,7 @@ macro_rules! decl_dispatch { $(#[$attr:meta])* pub enum $call_type:ident { $( + $(#[$fn_attr:meta])* fn $fn_name:ident( $( $param_name:ident : $param:ty @@ -179,6 +180,7 @@ macro_rules! decl_dispatch { $(#[$attr:meta])* pub enum $call_type:ident where aux: $aux_type:ty { $( + $(#[$fn_attr:meta])* fn $fn_name:ident(aux $( , $param_name:ident : $param:ty @@ -578,8 +580,8 @@ macro_rules! __impl_json_metadata { ) => { impl<$trait_instance: $trait_name> $mod_type<$trait_instance> { pub fn json_metadata() -> &'static str { - concat!(r#"{ "name": ""#, stringify!($mod_type), r#"", "calls": ["#, - __calls_to_json!(""; $($rest)*), " ] }") + concat!(r#"{ "name": ""#, stringify!($mod_type), r#"", "calls": ["#, + __calls_to_json!(""; $($rest)*), " ] }") } } } @@ -588,12 +590,13 @@ macro_rules! __impl_json_metadata { /// Convert the list of calls into their JSON representation, joined by ",". #[macro_export] macro_rules! __calls_to_json { - // WITHOUT AUX + // WITHOUT AUX ( $prefix_str:tt; $(#[$attr:meta])* pub enum $call_type:ident { $( + $(#[doc = $doc_attr:tt])* fn $fn_name:ident( $( $param_name:ident : $param:ty @@ -605,10 +608,11 @@ macro_rules! __calls_to_json { $($rest:tt)* ) => { concat!($prefix_str, " ", - r#"{ "name": ""#, stringify!($call_type), + r#"{ "name": ""#, stringify!($call_type), r#"", "functions": {"#, __functions_to_json!(""; $( fn $fn_name( $( $param_name: $param ),* ) -> $result = $id; + __function_doc_to_json!(""; $($doc_attr)*); )*), " } }", __calls_to_json!(","; $($rest)*) ) }; @@ -618,6 +622,7 @@ macro_rules! __calls_to_json { $(#[$attr:meta])* pub enum $call_type:ident where aux: $aux_type:ty { $( + $(#[doc = $doc_attr:tt])* fn $fn_name:ident(aux $( , $param_name:ident : $param:ty @@ -629,10 +634,11 @@ macro_rules! __calls_to_json { $($rest:tt)* ) => { concat!($prefix_str, " ", - r#"{ "name": ""#, stringify!($call_type), + r#"{ "name": ""#, stringify!($call_type), r#"", "functions": {"#, __functions_to_json!(""; $aux_type; $( fn $fn_name(aux $(, $param_name: $param )* ) -> $result = $id; + __function_doc_to_json!(""; $($doc_attr)*); )*), " } }", __calls_to_json!(","; $($rest)*) ) }; @@ -648,20 +654,22 @@ macro_rules! __calls_to_json { #[macro_export] macro_rules! __functions_to_json { // WITHOUT AUX - ( + ( $prefix_str:tt; - fn $fn_name:ident( + fn $fn_name:ident( $($param_name:ident : $param:ty),* ) -> $result:ty = $id:expr ; + $fn_doc:expr; $($rest:tt)* ) => { - concat!($prefix_str, " ", + concat!($prefix_str, " ", __function_to_json!( fn $fn_name( $($param_name : $param),* ) -> $result = $id ; + $fn_doc; ), __functions_to_json!(","; $($rest)*) - ) + ) }; // WITH AUX ( @@ -672,6 +680,7 @@ macro_rules! __functions_to_json { , $param_name:ident : $param:ty )* ) -> $result:ty = $id:expr ; + $fn_doc:expr; $($rest:tt)* ) => { concat!($prefix_str, " ", @@ -680,8 +689,9 @@ macro_rules! __functions_to_json { aux: $aux_type $(, $param_name : $param)* ) -> $result = $id ; + $fn_doc; ), __functions_to_json!(","; $aux_type; $($rest)*) - ) + ) }; // BASE CASE ( @@ -695,10 +705,11 @@ macro_rules! __functions_to_json { /// Convert a function into its JSON representation. #[macro_export] macro_rules! __function_to_json { - ( - fn $fn_name:ident( + ( + fn $fn_name:ident( $first_param_name:ident : $first_param:ty $(, $param_name:ident : $param:ty)* ) -> $result:ty = $id:expr ; + $fn_doc:tt; ) => { concat!( r#"""#, stringify!($id), r#"""#, @@ -708,11 +719,33 @@ macro_rules! __function_to_json { $( concat!(r#", { "name": ""#, stringify!($param_name), r#"", "type": ""#, stringify!($param), r#"" }"# ), )* - " ] }" + r#" ], "description": ["#, $fn_doc, " ] }" ) }; } +/// Convert a function documentation attribute into its JSON representation. +#[macro_export] +macro_rules! __function_doc_to_json { + ( + $prefix_str:tt; + $doc_attr:tt + $($rest:tt)* + ) => { + concat!( + $prefix_str, r#" ""#, + $doc_attr, + r#"""#, + __function_doc_to_json!(","; $($rest)*) + ) + }; + ( + $prefix_str:tt; + ) => { + "" + } +} + #[cfg(test)] // Do not complain about unused `dispatch` and `dispatch_aux`. #[allow(dead_code)] @@ -730,6 +763,7 @@ mod tests { #[derive(Serialize, Deserialize)] pub enum Call where aux: T::PublicAux { + /// Hi, this is a comment. fn aux_0(aux) -> Result = 0; fn aux_1(aux, data: i32) -> Result = 1; fn aux_2(aux, data: i32, data2: String) -> Result = 2; @@ -737,6 +771,8 @@ mod tests { #[derive(Serialize, Deserialize)] pub enum PrivCall { + /// Hi, this is a comment. + /// Hi, this is a second comment. fn priv_0(data: String) -> Result = 0; fn priv_1(data: String, data2: u32) -> Result = 1; } @@ -747,25 +783,25 @@ mod tests { r#"{ "name": "Call", "functions": { "#, r#""0": { "name": "aux_0", "params": [ "#, r#"{ "name": "aux", "type": "T::PublicAux" }"#, - r#" ] }, "#, + r#" ], "description": [ " Hi, this is a comment." ] }, "#, r#""1": { "name": "aux_1", "params": [ "#, r#"{ "name": "aux", "type": "T::PublicAux" }, "#, r#"{ "name": "data", "type": "i32" }"#, - r#" ] }, "#, + r#" ], "description": [ ] }, "#, r#""2": { "name": "aux_2", "params": [ "#, r#"{ "name": "aux", "type": "T::PublicAux" }, "#, r#"{ "name": "data", "type": "i32" }, "#, r#"{ "name": "data2", "type": "String" }"#, - r#" ] }"#, + r#" ], "description": [ ] }"#, r#" } }, "#, r#"{ "name": "PrivCall", "functions": { "#, r#""0": { "name": "priv_0", "params": [ "#, r#"{ "name": "data", "type": "String" }"#, - r#" ] }, "#, + r#" ], "description": [ " Hi, this is a comment.", " Hi, this is a second comment." ] }, "#, r#""1": { "name": "priv_1", "params": [ "#, r#"{ "name": "data", "type": "String" }, "#, r#"{ "name": "data2", "type": "u32" }"#, - r#" ] }"#, + r#" ], "description": [ ] }"#, r#" } }"#, r#" ] }"#, );