macro_rules! build_struct_json_patch { ( $($struct_type:ident)::+ { $($body:tt)* } ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ { $($body:tt)* }) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* } ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $($type:ident)::+ { $($body:tt)* }, $($tail:tt)*) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr, $($tail:tt)* ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident, $($tail:tt)* ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $key:ident ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ ..$update:expr ) => { ... }; ($($struct_type:ident)::+, $all_keys:ident @ $(,)?) => { ... }; }
Expand description
Creates a JSON patch for given struct_type
, supporting recursive field initialization.
This macro creates a default struct_type
, initializing specified fields (which can be nested)
with the provided values. Any fields not explicitly given are initialized with their default
values. The macro then serializes the fully initialized structure into a JSON blob, retaining
only the fields that were explicitly provided, either partially or fully initialized.
Using this macro prevents errors from manually creating JSON objects, such as typos or
inconsistencies with the struct_type
structure, by relying on the actual
struct definition. This ensures the generated JSON is valid and reflects any future changes
to the structure.
§Example
use frame_support::build_struct_json_patch;
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct RuntimeGenesisConfig {
a_field: u32,
b_field: B,
c_field: u32,
}
#[derive(Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct B {
i_field: u32,
j_field: u32,
}
impl B {
fn new() -> Self {
Self { i_field: 0, j_field: 2 }
}
}
assert_eq!(
build_struct_json_patch! ( RuntimeGenesisConfig {
a_field: 66,
}),
serde_json::json!({
"aField": 66,
})
);
assert_eq!(
build_struct_json_patch! ( RuntimeGenesisConfig {
//"partial" initialization of `b_field`
b_field: B {
i_field: 2,
}
}),
serde_json::json!({
"bField": {"iField": 2}
})
);
assert_eq!(
build_struct_json_patch! ( RuntimeGenesisConfig {
a_field: 66,
//"full" initialization of `b_field`
b_field: B::new()
}),
serde_json::json!({
"aField": 66,
"bField": {"iField": 0, "jField": 2}
})
);
In this example:
build_struct_json_patch! ( RuntimeGenesisConfig {
b_field: B {
i_field: 2,
}
}),
b_field
is partially initialized, it will be expanded to:
RuntimeGenesisConfig {
b_field {
i_field: 2,
..Default::default()
},
..Default::default()
}
While all other fields are initialized with default values. The macro serializes this, retaining only the provided fields.