referrerpolicy=no-referrer-when-downgrade

frame_support/
generate_genesis_config.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Helper macro allowing to construct JSON representation of partially initialized structs.
19
20use serde_json::Value;
21extern crate alloc;
22use alloc::{borrow::Cow, format, string::String};
23
24/// Represents the initialization method of a field within a struct.
25///
26/// This enum provides information about how it was initialized.
27///
28/// Intended to be used in `build_struct_json_patch` macro.
29#[derive(Debug)]
30pub enum InitilizationType {
31	/// The field was partially initialized (e.g., specific fields within the struct were set
32	/// manually).
33	Partial,
34	/// The field was fully initialized (e.g., using `new()` or `default()` like methods
35	Full,
36}
37
38/// This struct provides information about how the struct field was initialized and the field name
39/// (as a `&str`).
40///
41/// Intended to be used in `build_struct_json_patch` macro.
42#[derive(Debug)]
43pub struct InitializedField<'a>(InitilizationType, Cow<'a, str>);
44
45impl<'a> InitializedField<'a> {
46	/// Returns a name of the field.
47	pub fn get_name(&'a self) -> &'a str {
48		&self.1
49	}
50
51	/// Injects a prefix to the field name.
52	pub fn add_prefix(&mut self, prefix: &str) {
53		self.1 = format!("{prefix}.{}", self.1).into()
54	}
55
56	/// Creates new partial field instiance.
57	pub fn partial(s: &'a str) -> Self {
58		Self(InitilizationType::Partial, s.into())
59	}
60
61	/// Creates new full field instiance.
62	pub fn full(s: &'a str) -> Self {
63		Self(InitilizationType::Full, s.into())
64	}
65}
66
67impl PartialEq<String> for InitializedField<'_> {
68	fn eq(&self, other: &String) -> bool {
69		#[inline]
70		/// We need to respect the `camelCase` naming for field names. This means that
71		/// `"camelCaseKey"` should be considered equal to `"camel_case_key"`. This
72		/// function implements this comparison.
73		fn compare_keys(ident_chars: core::str::Chars, camel_chars: core::str::Chars) -> bool {
74			ident_chars
75				.filter(|c| *c != '_')
76				.map(|c| c.to_ascii_uppercase())
77				.eq(camel_chars.map(|c| c.to_ascii_uppercase()))
78		}
79		*self.1 == *other || compare_keys(self.1.chars(), other.chars())
80	}
81}
82
83impl<'a> From<(InitilizationType, &'a str)> for InitializedField<'a> {
84	fn from(value: (InitilizationType, &'a str)) -> Self {
85		match value.0 {
86			InitilizationType::Full => InitializedField::full(value.1),
87			InitilizationType::Partial => InitializedField::partial(value.1),
88		}
89	}
90}
91
92/// Recursively removes keys from provided `json_value` object, retaining only specified keys.
93///
94/// This function modifies the provided `json_value` in-place, keeping only the keys listed in
95/// `keys_to_retain`. The keys are matched recursively by combining the current key with
96/// the `current_root`, allowing for nested field retention.
97///
98/// Keys marked as `Full`, are retained as-is. For keys marked as `Partial`, the
99/// function recurses into nested objects to retain matching subfields.
100///
101/// Function respects the `camelCase` serde_json attribute for structures. This means that
102/// `"camelCaseKey"` key will be retained in JSON blob if `"camel_case_key"` exists in
103/// `keys_to_retain`.
104///
105/// Intended to be used from `build_struct_json_patch` macro.
106pub fn retain_initialized_fields(
107	json_value: &mut Value,
108	keys_to_retain: &[InitializedField],
109	current_root: String,
110) {
111	if let serde_json::Value::Object(ref mut map) = json_value {
112		map.retain(|key, value| {
113			let current_key =
114				if current_root.is_empty() { key.clone() } else { format!("{current_root}.{key}") };
115			match keys_to_retain.iter().find(|key| **key == current_key) {
116				Some(InitializedField(InitilizationType::Full, _)) => true,
117				Some(InitializedField(InitilizationType::Partial, _)) => {
118					retain_initialized_fields(value, keys_to_retain, current_key.clone());
119					true
120				},
121				None => false,
122			}
123		})
124	}
125}
126
127/// Creates a JSON patch for given `struct_type`, supporting recursive field initialization.
128///
129/// This macro creates a default `struct_type`, initializing specified fields (which can be nested)
130/// with the provided values. Any fields not explicitly given are initialized with their default
131/// values. The macro then serializes the fully initialized structure into a JSON blob, retaining
132/// only the fields that were explicitly provided, either partially or fully initialized.
133///
134/// Using this macro prevents errors from manually creating JSON objects, such as typos or
135/// inconsistencies with the `struct_type` structure, by relying on the actual
136/// struct definition. This ensures the generated JSON is valid and reflects any future changes
137/// to the structure.
138///
139/// # Example
140///
141/// ```rust
142/// use frame_support::build_struct_json_patch;
143/// #[derive(Default, serde::Serialize, serde::Deserialize)]
144/// #[serde(rename_all = "camelCase")]
145/// struct RuntimeGenesisConfig {
146///     a_field: u32,
147///     b_field: B,
148///     c_field: u32,
149/// }
150///
151/// #[derive(Default, serde::Serialize, serde::Deserialize)]
152/// #[serde(rename_all = "camelCase")]
153/// struct B {
154/// 	i_field: u32,
155/// 	j_field: u32,
156/// }
157/// impl B {
158/// 	fn new() -> Self {
159/// 		Self { i_field: 0, j_field: 2 }
160/// 	}
161/// }
162///
163/// assert_eq!(
164/// 	build_struct_json_patch! ( RuntimeGenesisConfig {
165/// 		a_field: 66,
166/// 	}),
167/// 	serde_json::json!({
168/// 			"aField": 66,
169/// 	})
170/// );
171///
172/// assert_eq!(
173/// 	build_struct_json_patch! ( RuntimeGenesisConfig {
174/// 		//"partial" initialization of `b_field`
175/// 		b_field: B {
176/// 			i_field: 2,
177/// 		}
178/// 	}),
179/// 	serde_json::json!({
180/// 		"bField": {"iField": 2}
181/// 	})
182/// );
183///
184/// assert_eq!(
185/// 	build_struct_json_patch! ( RuntimeGenesisConfig {
186/// 		a_field: 66,
187/// 		//"full" initialization of `b_field`
188/// 		b_field: B::new()
189/// 	}),
190/// 	serde_json::json!({
191/// 		"aField": 66,
192/// 		"bField": {"iField": 0, "jField": 2}
193/// 	})
194/// );
195/// ```
196///
197/// In this example:
198/// ```ignore
199/// 	build_struct_json_patch! ( RuntimeGenesisConfig {
200/// 		b_field: B {
201/// 			i_field: 2,
202/// 		}
203/// 	}),
204/// ```
205/// `b_field` is partially initialized, it will be expanded to:
206/// ```ignore
207/// RuntimeGenesisConfig {
208/// 		b_field {
209/// 			i_field: 2,
210/// 			..Default::default()
211/// 		},
212/// 		..Default::default()
213/// }
214/// ```
215/// While all other fields are initialized with default values. The macro serializes this, retaining
216/// only the provided fields.
217#[macro_export]
218macro_rules! build_struct_json_patch {
219	(
220		$($struct_type:ident)::+ { $($body:tt)* }
221	) => {
222		{
223			let mut __keys = $crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default();
224			#[allow(clippy::needless_update)]
225			let __struct_instance = $crate::build_struct_json_patch!($($struct_type)::+, __keys @  { $($body)* }).0;
226			let mut __json_value =
227				$crate::__private::serde_json::to_value(__struct_instance).expect("serialization to json should work. qed");
228			$crate::generate_genesis_config::retain_initialized_fields(&mut __json_value, &__keys, Default::default());
229			__json_value
230		}
231	};
232	($($struct_type:ident)::+, $all_keys:ident @ { $($body:tt)* }) => {
233		{
234			let __value = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($body)*);
235			(
236				$($struct_type)::+ { ..__value.0 },
237				__value.1
238			)
239		}
240	};
241	($($struct_type:ident)::+, $all_keys:ident @ $key:ident:  $($type:ident)::+ { $($body:tt)* } ) => {
242		(
243			$($struct_type)::+ {
244				$key: {
245					let mut __inner_keys =
246						$crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default();
247					let __value = $crate::build_struct_json_patch!($($type)::+, __inner_keys @ { $($body)* });
248					for i in __inner_keys.iter_mut() {
249						i.add_prefix(stringify!($key));
250					};
251					$all_keys.push((__value.1,stringify!($key)).into());
252					$all_keys.extend(__inner_keys);
253					__value.0
254				},
255				..Default::default()
256			},
257			$crate::generate_genesis_config::InitilizationType::Partial
258		)
259	};
260	($($struct_type:ident)::+, $all_keys:ident @ $key:ident:  $($type:ident)::+ { $($body:tt)* },  $($tail:tt)*) => {
261		{
262			let mut __initialization_type;
263			(
264				$($struct_type)::+ {
265					$key : {
266						let mut __inner_keys =
267							$crate::__private::Vec::<$crate::generate_genesis_config::InitializedField>::default();
268						let __value = $crate::build_struct_json_patch!($($type)::+, __inner_keys @ { $($body)* });
269						$all_keys.push((__value.1,stringify!($key)).into());
270
271						for i in __inner_keys.iter_mut() {
272							i.add_prefix(stringify!($key));
273						};
274						$all_keys.extend(__inner_keys);
275						__value.0
276					},
277					.. {
278						let (__value, __tmp) =
279							$crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*);
280						__initialization_type = __tmp;
281						__value
282					}
283				},
284				__initialization_type
285			)
286		}
287	};
288	($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr, $($tail:tt)* ) => {
289		{
290			let mut __initialization_type;
291			(
292				$($struct_type)::+ {
293					$key: {
294						$all_keys.push($crate::generate_genesis_config::InitializedField::full(
295							stringify!($key))
296						);
297						$value
298					},
299					.. {
300						let (__value, __tmp) =
301							$crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*);
302						__initialization_type = __tmp;
303						__value
304					}
305				},
306				__initialization_type
307			)
308		}
309	};
310	($($struct_type:ident)::+, $all_keys:ident @ $key:ident: $value:expr ) => {
311		(
312			$($struct_type)::+ {
313				$key: {
314					$all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key)));
315					$value
316				},
317				..Default::default()
318			},
319			$crate::generate_genesis_config::InitilizationType::Partial
320		)
321	};
322	// field init shorthand
323	($($struct_type:ident)::+, $all_keys:ident @ $key:ident, $($tail:tt)* ) => {
324		{
325			let __update = $crate::build_struct_json_patch!($($struct_type)::+, $all_keys @ $($tail)*);
326			(
327				$($struct_type)::+ {
328					$key: {
329						$all_keys.push($crate::generate_genesis_config::InitializedField::full(
330							stringify!($key))
331						);
332						$key
333					},
334					..__update.0
335				},
336				__update.1
337			)
338		}
339	};
340	($($struct_type:ident)::+, $all_keys:ident @ $key:ident ) => {
341		(
342			$($struct_type)::+ {
343				$key: {
344					$all_keys.push($crate::generate_genesis_config::InitializedField::full(stringify!($key)));
345					$key
346				},
347				..Default::default()
348			},
349			$crate::generate_genesis_config::InitilizationType::Partial
350		)
351	};
352	// update struct
353	($($struct_type:ident)::+, $all_keys:ident @ ..$update:expr ) => {
354		(
355			$($struct_type)::+ {
356				..$update
357			},
358			$crate::generate_genesis_config::InitilizationType::Full
359		)
360	};
361	($($struct_type:ident)::+, $all_keys:ident  @ $(,)?) => {
362		(
363			$($struct_type)::+ {
364				..Default::default()
365			},
366			$crate::generate_genesis_config::InitilizationType::Partial
367		)
368	};
369}
370
371#[cfg(test)]
372mod test {
373	mod nested_mod {
374		#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
375		pub struct InsideMod {
376			pub a: u32,
377			pub b: u32,
378		}
379
380		pub mod nested_mod2 {
381			pub mod nested_mod3 {
382				#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
383				pub struct InsideMod3 {
384					pub a: u32,
385					pub b: u32,
386					pub s: super::super::InsideMod,
387				}
388			}
389		}
390	}
391
392	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
393	struct TestStruct {
394		a: u32,
395		b: u32,
396		s: S,
397		s3: S3,
398		t3: S3,
399		i: Nested1,
400		e: E,
401		t: nested_mod::InsideMod,
402		u: nested_mod::nested_mod2::nested_mod3::InsideMod3,
403	}
404
405	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
406	struct S {
407		x: u32,
408	}
409
410	impl S {
411		fn new(c: u32) -> Self {
412			Self { x: c }
413		}
414	}
415
416	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
417	struct E(u8);
418
419	#[derive(Default, Debug, serde::Serialize, serde::Deserialize)]
420	enum SomeEnum<T> {
421		#[default]
422		A,
423		B(T),
424	}
425
426	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
427	struct S3 {
428		x: u32,
429		y: u32,
430		z: u32,
431	}
432
433	impl S3 {
434		fn new(c: u32) -> Self {
435			Self { x: c, y: c, z: c }
436		}
437
438		fn new_from_s(s: S) -> Self {
439			Self { x: s.x, ..Default::default() }
440		}
441	}
442
443	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
444	struct Nested3 {
445		a: u32,
446		b: u32,
447		s: S,
448		v: Vec<(u32, u32, u32, SomeEnum<u32>)>,
449	}
450
451	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
452	struct Nested2 {
453		a: u32,
454		iii: Nested3,
455		v: Vec<u32>,
456		s3: S3,
457	}
458
459	impl Nested2 {
460		fn new(a: u32) -> Self {
461			Nested2 {
462				a,
463				v: vec![a, a, a],
464				iii: Nested3 { a, b: a, ..Default::default() },
465				s3: S3 { x: a, ..Default::default() },
466			}
467		}
468	}
469
470	#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
471	struct Nested1 {
472		a: u32,
473		ii: Nested2,
474	}
475
476	macro_rules! test {
477		($($struct:ident)::+ { $($v:tt)* }, { $($j:tt)* } ) => {{
478			let expected = serde_json::json!({ $($j)* });
479			let value = build_struct_json_patch!($($struct)::+ { $($v)* });
480			assert_eq!(value, expected);
481		}};
482	}
483
484	#[test]
485	fn test_generate_config_macro() {
486		let t = 5;
487		const C: u32 = 5;
488		test!(TestStruct { b: 5 }, { "b": 5 });
489		test!(TestStruct { b: 5, }, { "b": 5 });
490		#[allow(unused_braces)]
491		{
492			test!(TestStruct { b: { 4 + 34 } } , { "b": 38 });
493		}
494		test!(TestStruct { s: S { x: 5 } }, { "s": { "x": 5 } });
495		test!(
496			TestStruct { s: S::new(C) },
497			{
498				"s": { "x": 5 }
499			}
500		);
501		test!(
502			TestStruct { s: S { x: t } },
503			{
504				"s": { "x": t }
505			}
506		);
507		test!(
508			TestStruct {
509				b: 5,
510				s: S { x: t }
511			},
512			{
513				"b": 5,
514				"s": { "x": 5 }
515			}
516		);
517		test!(
518			TestStruct { s: S::new(C), b: 5 },
519			{
520				"s": { "x": 5 }, "b": 5
521			}
522		);
523		test!(
524			TestStruct { s3: S3 { x: t } },
525			{
526				"s3": { "x": 5 }
527			}
528		);
529		test!(
530			TestStruct {
531				s3: S3 { x: t, y: 2 }
532			},
533			{
534				"s3": { "x": 5, "y": 2 }
535			}
536		);
537		// //
538		test!(
539			TestStruct {
540				s3: S3 { x: t, y: 2 },
541				t3: S3 { x: 2 }
542			},
543			{
544				"s3": { "x": t, "y": 2 },
545				"t3": { "x": 2 }
546			}
547
548		);
549		test!(
550			TestStruct {
551				i: Nested1 {
552					ii: Nested2 { iii: Nested3 { a: 2 } }
553				}
554			}
555			,
556			{
557				"i":  {
558					"ii": { "iii": { "a": 2 } }
559				}
560			}
561
562		);
563		test!(
564			TestStruct {
565				i: Nested1 {
566					ii: Nested2 {
567						iii: Nested3 { a: 2, s: S::new(C) }
568					}
569				}
570			},
571			{
572				"i": {
573					"ii": {
574						"iii": { "a": 2, "s": { "x": 5} }
575					}
576				}
577			}
578		);
579		test!(
580			TestStruct {
581				i: Nested1 {
582					ii: Nested2 {
583						iii: Nested3 { s: S::new(C), a: 2 }
584					},
585					a: 44
586				},
587				a: 3,
588				s3: S3 { x: 5 },
589				b: 4
590			},
591			{
592				"i": {
593					"ii": {
594						"iii": { "a": 2, "s": { "x": 5} }
595					},
596					"a": 44
597				},
598				"a": 3,
599				"s3": { "x": 5 },
600				"b": 4
601			}
602		);
603		test!(
604			TestStruct {
605				i: Nested1 {
606					ii: Nested2::new(66),
607					a: 44,
608				},
609				a: 3,
610				s3: S3 { x: 5 },
611				b: 4
612			},
613			{
614				"i": {
615					"ii": {
616						"a": 66,
617						"s3": { "x":66, "y": 0, "z": 0 },
618						"iii": { "a": 66,"b":66, "s": { "x": 0 }, "v": Vec::<u32>::default() },
619						"v": vec![66,66,66]
620					},
621					"a": 44
622				},
623				"a": 3,
624				"s3": { "x": 5 },
625				"b": 4
626			}
627		);
628
629		test!(
630			TestStruct {
631				i: Nested1 {
632					ii: Nested2 {
633						a: 66,
634						s3: S3 { x: 66 },
635						iii: Nested3 {
636							a: 66,b:66
637						},
638						v: vec![66,66,66]
639					},
640					a: 44,
641				},
642				a: 3,
643				s3: S3 { x: 5 },
644				b: 4
645			},
646			{
647				"i": {
648					"ii": {
649						"a": 66,
650						"s3": { "x":66,  },
651						"iii": { "a": 66,"b":66, },
652						"v": vec![66,66,66]
653					},
654					"a": 44
655				},
656				"a": 3,
657				"s3": { "x": 5 },
658				"b": 4
659			}
660		);
661
662		test!(
663			TestStruct {
664				i: Nested1 {
665					ii: Nested2 {
666						iii: Nested3 { a: 2, s: S::new(C) },
667					},
668					a: 44,
669				},
670				a: 3,
671				s3: S3 { x: 5 },
672				b: 4,
673			},
674			{
675				"i": {
676					"ii": {
677						"iii": { "a": 2, "s": { "x": 5 } },
678					},
679					"a" : 44,
680				},
681				"a": 3,
682				"s3": { "x": 5 },
683				"b": 4
684			}
685		);
686		test!(
687			TestStruct {
688				i: Nested1 {
689					ii: Nested2 {
690						s3: S3::new(5),
691						iii: Nested3 { a: 2, s: S::new(C) },
692					},
693					a: 44,
694				},
695				a: 3,
696				s3: S3 { x: 5 },
697				b: 4,
698			},
699			{
700				"i": {
701					"ii": {
702						"iii": { "a": 2, "s": { "x": 5 } },
703						"s3": {"x": 5, "y": 5, "z": 5 }
704					},
705					"a" : 44,
706				},
707				"a": 3,
708				"s3": { "x": 5 },
709				"b": 4
710			}
711		);
712		test!(
713			TestStruct {
714				a: 3,
715				s3: S3 { x: 5 },
716				b: 4,
717				i: Nested1 {
718					ii: Nested2 {
719						iii: Nested3 { a: 2, s: S::new(C) },
720						s3: S3::new_from_s(S { x: 4 })
721					},
722					a: 44,
723				}
724			},
725			{
726				"i": {
727					"ii": {
728						"iii": { "a": 2, "s": { "x": 5 } },
729						"s3": {"x": 4, "y": 0, "z": 0 }
730					},
731					"a" : 44,
732				},
733				"a": 3,
734				"s3": { "x": 5 },
735				"b": 4
736			}
737		);
738		let i = [0u32, 1u32, 2u32];
739		test!(
740			TestStruct {
741				i: Nested1 {
742					ii: Nested2 {
743						iii: Nested3 {
744							a: 2,
745							s: S::new(C),
746							v: i.iter()
747								.map(|x| (*x, 2 * x, 100 + x, SomeEnum::<u32>::A))
748								.collect::<Vec<_>>(),
749						},
750						s3: S3::new_from_s(S { x: 4 })
751					},
752					a: 44,
753				},
754				a: 3,
755				s3: S3 { x: 5 },
756				b: 4,
757			},
758
759			{
760				"i": {
761					"ii": {
762						"iii": {
763							"a": 2,
764							"s": { "x": 5 },
765							"v": i.iter()
766								.map(|x| (*x, 2 * x, 100 + x, SomeEnum::<u32>::A))
767								.collect::<Vec<_>>(),
768						},
769						"s3": {"x": 4, "y": 0, "z": 0 }
770					},
771					"a" : 44,
772				},
773				"a": 3,
774				"s3": { "x": 5 },
775				"b": 4
776			}
777		);
778	}
779
780	#[test]
781	fn test_generate_config_macro_field_init_shorthand() {
782		{
783			let x = 5;
784			test!(TestStruct { s: S { x } }, { "s": { "x": 5 } });
785		}
786		{
787			let s = nested_mod::InsideMod { a: 34, b: 8 };
788			test!(
789				TestStruct {
790					t: nested_mod::InsideMod { a: 32 },
791					u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
792						s,
793						a: 32,
794					}
795				},
796				{
797					"t" : { "a": 32 },
798					"u" : { "a": 32, "s": { "a": 34, "b": 8} }
799				}
800			);
801		}
802		{
803			let s = nested_mod::InsideMod { a: 34, b: 8 };
804			test!(
805				TestStruct {
806					t: nested_mod::InsideMod { a: 32 },
807					u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
808						a: 32,
809						s,
810					}
811				},
812				{
813					"t" : { "a": 32 },
814					"u" : { "a": 32, "s": { "a": 34, "b": 8} }
815				}
816			);
817		}
818	}
819
820	#[test]
821	fn test_generate_config_macro_struct_update() {
822		{
823			let s = S { x: 5 };
824			test!(TestStruct { s: S { ..s } }, { "s": { "x": 5 } });
825		}
826		{
827			mod nested {
828				use super::*;
829				pub fn function() -> S {
830					S { x: 5 }
831				}
832			}
833			test!(TestStruct { s: S { ..nested::function() } }, { "s": { "x": 5 } });
834		}
835		{
836			let s = nested_mod::InsideMod { a: 34, b: 8 };
837			let s1 = nested_mod::InsideMod { a: 34, b: 8 };
838			test!(
839				TestStruct {
840					t: nested_mod::InsideMod { ..s1 },
841					u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
842						s,
843						a: 32,
844					}
845				},
846				{
847					"t" : { "a": 34, "b": 8 },
848					"u" : { "a": 32, "s": { "a": 34, "b": 8} }
849				}
850			);
851		}
852		{
853			let i3 = nested_mod::nested_mod2::nested_mod3::InsideMod3 {
854				a: 1,
855				b: 2,
856				s: nested_mod::InsideMod { a: 55, b: 88 },
857			};
858			test!(
859				TestStruct {
860					t: nested_mod::InsideMod { a: 32 },
861					u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
862						a: 32,
863						..i3
864					}
865				},
866				{
867					"t" : { "a": 32 },
868					"u" : { "a": 32, "b": 2, "s": { "a": 55, "b": 88} }
869				}
870			);
871		}
872		{
873			let s = nested_mod::InsideMod { a: 34, b: 8 };
874			test!(
875				TestStruct {
876					t: nested_mod::InsideMod { a: 32 },
877					u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
878						a: 32,
879						s: nested_mod::InsideMod  {
880							b: 66,
881							..s
882						}
883					}
884				},
885				{
886					"t" : { "a": 32 },
887					"u" : { "a": 32, "s": { "a": 34, "b": 66} }
888				}
889			);
890		}
891		{
892			let s = nested_mod::InsideMod { a: 34, b: 8 };
893			test!(
894				TestStruct {
895					t: nested_mod::InsideMod { a: 32 },
896					u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
897						s: nested_mod::InsideMod  {
898							b: 66,
899							..s
900						},
901						a: 32
902					}
903				},
904				{
905					"t" : { "a": 32 },
906					"u" : { "a": 32, "s": { "a": 34, "b": 66} }
907				}
908			);
909		}
910	}
911
912	#[test]
913	fn test_generate_config_macro_with_execution_order() {
914		#[derive(Debug, Default, serde::Serialize, serde::Deserialize, PartialEq)]
915		struct X {
916			x: Vec<u32>,
917			x2: Vec<u32>,
918			y2: Y,
919		}
920		#[derive(Debug, Default, serde::Serialize, serde::Deserialize, PartialEq)]
921		struct Y {
922			y: Vec<u32>,
923		}
924		#[derive(Debug, Default, serde::Serialize, serde::Deserialize, PartialEq)]
925		struct Z {
926			a: u32,
927			x: X,
928			y: Y,
929		}
930		{
931			let v = vec![1, 2, 3];
932			test!(Z { a: 0, x: X { x: v },  }, {
933				"a": 0, "x": { "x": [1,2,3] }
934			});
935		}
936		{
937			let v = vec![1, 2, 3];
938			test!(Z { a: 3, x: X { x: v.clone() }, y: Y { y: v } }, {
939				"a": 3, "x": { "x": [1,2,3] }, "y": { "y": [1,2,3] }
940			});
941		}
942		{
943			let v = vec![1, 2, 3];
944			test!(Z { a: 3, x: X { y2: Y { y: v.clone() }, x: v.clone() }, y: Y { y: v } }, {
945				"a": 3, "x": { "x": [1,2,3], "y2":{ "y":[1,2,3] } }, "y": { "y": [1,2,3] }
946			});
947		}
948		{
949			let v = vec![1, 2, 3];
950			test!(Z { a: 3, y: Y { y: v.clone() }, x: X { y2: Y { y: v.clone() }, x: v },  }, {
951				"a": 3, "x": { "x": [1,2,3], "y2":{ "y":[1,2,3] } }, "y": { "y": [1,2,3] }
952			});
953		}
954		{
955			let v = vec![1, 2, 3];
956			test!(
957				Z {
958					y: Y {
959						y: v.clone()
960					},
961					x: X {
962						y2: Y {
963							y: v.clone()
964						},
965						x: v.clone(),
966						x2: v.clone()
967					},
968				},
969				{
970					"x": {
971						"x": [1,2,3],
972						"x2": [1,2,3],
973						"y2": {
974							"y":[1,2,3]
975						}
976					},
977					"y": {
978						"y": [1,2,3]
979					}
980			});
981		}
982		{
983			let v = vec![1, 2, 3];
984			test!(
985				Z {
986					y: Y {
987						y: v.clone()
988					},
989					x: X {
990						y2: Y {
991							y: v.clone()
992						},
993						x: v
994					},
995				},
996				{
997					"x": {
998						"x": [1,2,3],
999						"y2": {
1000							"y":[1,2,3]
1001						}
1002					},
1003					"y": {
1004						"y": [1,2,3]
1005					}
1006			});
1007		}
1008		{
1009			let mut v = vec![0, 1, 2];
1010			let f = |vec: &mut Vec<u32>| -> Vec<u32> {
1011				vec.iter_mut().for_each(|x| *x += 1);
1012				vec.clone()
1013			};
1014			let z = Z {
1015				a: 0,
1016				y: Y { y: f(&mut v) },
1017				x: X { y2: Y { y: f(&mut v) }, x: f(&mut v), x2: vec![] },
1018			};
1019			let z_expected = Z {
1020				a: 0,
1021				y: Y { y: vec![1, 2, 3] },
1022				x: X { y2: Y { y: vec![2, 3, 4] }, x: vec![3, 4, 5], x2: vec![] },
1023			};
1024			assert_eq!(z, z_expected);
1025			v = vec![0, 1, 2];
1026			println!("{z:?}");
1027			test!(
1028				Z {
1029					y: Y {
1030						y: f(&mut v)
1031					},
1032					x: X {
1033						y2: Y {
1034							y: f(&mut v)
1035						},
1036						x: f(&mut v)
1037					},
1038				},
1039				{
1040					"y": {
1041						"y": [1,2,3]
1042					},
1043					"x": {
1044						"y2": {
1045							"y":[2,3,4]
1046						},
1047						"x": [3,4,5],
1048					},
1049			});
1050		}
1051		{
1052			let mut v = vec![0, 1, 2];
1053			let f = |vec: &mut Vec<u32>| -> Vec<u32> {
1054				vec.iter_mut().for_each(|x| *x += 1);
1055				vec.clone()
1056			};
1057			let z = Z {
1058				a: 0,
1059				y: Y { y: f(&mut v) },
1060				x: X { y2: Y { y: f(&mut v) }, x: f(&mut v), x2: f(&mut v) },
1061			};
1062			let z_expected = Z {
1063				a: 0,
1064				y: Y { y: vec![1, 2, 3] },
1065				x: X { y2: Y { y: vec![2, 3, 4] }, x: vec![3, 4, 5], x2: vec![4, 5, 6] },
1066			};
1067			assert_eq!(z, z_expected);
1068			v = vec![0, 1, 2];
1069			println!("{z:?}");
1070			test!(
1071				Z {
1072					y: Y {
1073						y: f(&mut v)
1074					},
1075					x: X {
1076						y2: Y {
1077							y: f(&mut v)
1078						},
1079						x: f(&mut v),
1080						x2: f(&mut v)
1081					},
1082				},
1083				{
1084					"y": {
1085						"y": [1,2,3]
1086					},
1087					"x": {
1088						"y2": {
1089							"y":[2,3,4]
1090						},
1091						"x": [3,4,5],
1092						"x2": [4,5,6],
1093					},
1094			});
1095		}
1096	}
1097
1098	#[test]
1099	fn test_generate_config_macro_with_nested_mods() {
1100		test!(
1101			TestStruct { t: nested_mod::InsideMod { a: 32 } },
1102			{
1103				"t" : { "a": 32 }
1104			}
1105		);
1106		test!(
1107			TestStruct {
1108				t: nested_mod::InsideMod { a: 32 },
1109				u: nested_mod::nested_mod2::nested_mod3::InsideMod3 { a: 32 }
1110			},
1111			{
1112				"t" : { "a": 32 },
1113				"u" : { "a": 32 }
1114			}
1115		);
1116		test!(
1117			TestStruct {
1118				t: nested_mod::InsideMod { a: 32 },
1119				u: nested_mod::nested_mod2::nested_mod3::InsideMod3 {
1120					a: 32,
1121					s: nested_mod::InsideMod { a: 34 },
1122				}
1123			},
1124			{
1125				"t" : { "a": 32 },
1126				"u" : { "a": 32, "s": { "a": 34 } }
1127			}
1128		);
1129		test!(
1130			TestStruct {
1131				t: nested_mod::InsideMod { a: 32 },
1132				u: nested_mod::nested_mod2::nested_mod3::InsideMod3::default()
1133			},
1134			{
1135				"t" : { "a": 32 },
1136				"u" : { "a": 0, "b": 0,  "s": { "a": 0, "b": 0} }
1137			}
1138		);
1139
1140		let i = [0u32, 1u32, 2u32];
1141		const C: u32 = 5;
1142		test!(
1143			TestStruct {
1144				t: nested_mod::InsideMod { a: 32 },
1145				u: nested_mod::nested_mod2::nested_mod3::InsideMod3::default(),
1146				i: Nested1 {
1147					ii: Nested2 {
1148						iii: Nested3 {
1149							a: 2,
1150							s: S::new(C),
1151							v: i.iter()
1152								.map(|x| (*x, 2 * x, 100 + x, SomeEnum::<u32>::A))
1153								.collect::<Vec<_>>(),
1154						},
1155						s3: S3::new_from_s(S { x: 4 })
1156					},
1157					a: 44,
1158				},
1159			},
1160			{
1161				"t" : { "a": 32 },
1162				"u" : { "a": 0, "b": 0,  "s": { "a": 0, "b": 0} } ,
1163				"i": {
1164					"ii": {
1165						"iii": {
1166							"a": 2,
1167							"s": { "x": 5 },
1168							"v": i.iter()
1169								.map(|x| (*x, 2 * x, 100 + x, SomeEnum::<u32>::A))
1170								.collect::<Vec<_>>(),
1171						},
1172						"s3": {"x": 4, "y": 0, "z": 0 }
1173					},
1174					"a" : 44,
1175				},
1176			}
1177		);
1178	}
1179}
1180
1181#[cfg(test)]
1182mod retain_keys_test {
1183	use super::*;
1184	use serde_json::json;
1185
1186	macro_rules! check_initialized_field_eq_cc(
1187		( $s:literal ) => {
1188			let field = InitializedField::full($s);
1189			let cc = inflector::cases::camelcase::to_camel_case($s);
1190			assert_eq!(field,cc);
1191		} ;
1192		( &[ $f:literal $(, $r:literal)* ]) => {
1193			let field = InitializedField::full(
1194				concat!( $f $(,".",$r)+ )
1195			);
1196			let cc = [ $f $(,$r)+  ].into_iter()
1197				.map(|s| inflector::cases::camelcase::to_camel_case(s))
1198				.collect::<Vec<_>>()
1199				.join(".");
1200			assert_eq!(field,cc);
1201		} ;
1202	);
1203
1204	#[test]
1205	fn test_initialized_field_eq_cc_string() {
1206		check_initialized_field_eq_cc!("a_");
1207		check_initialized_field_eq_cc!("abc");
1208		check_initialized_field_eq_cc!("aBc");
1209		check_initialized_field_eq_cc!("aBC");
1210		check_initialized_field_eq_cc!("ABC");
1211		check_initialized_field_eq_cc!("2abs");
1212		check_initialized_field_eq_cc!("2Abs");
1213		check_initialized_field_eq_cc!("2ABs");
1214		check_initialized_field_eq_cc!("2aBs");
1215		check_initialized_field_eq_cc!("AlreadyCamelCase");
1216		check_initialized_field_eq_cc!("alreadyCamelCase");
1217		check_initialized_field_eq_cc!("C");
1218		check_initialized_field_eq_cc!("1a");
1219		check_initialized_field_eq_cc!("_1a");
1220		check_initialized_field_eq_cc!("a_b");
1221		check_initialized_field_eq_cc!("_a_b");
1222		check_initialized_field_eq_cc!("a___b");
1223		check_initialized_field_eq_cc!("__a_b");
1224		check_initialized_field_eq_cc!("_a___b_C");
1225		check_initialized_field_eq_cc!("__A___B_C");
1226		check_initialized_field_eq_cc!(&["a_b", "b_c"]);
1227		check_initialized_field_eq_cc!(&["al_pha", "_a___b_C"]);
1228		check_initialized_field_eq_cc!(&["al_pha_", "_a___b_C"]);
1229		check_initialized_field_eq_cc!(&["first_field", "al_pha_", "_a___b_C"]);
1230		check_initialized_field_eq_cc!(&["al_pha_", "__2nd_field", "_a___b_C"]);
1231		check_initialized_field_eq_cc!(&["al_pha_", "__2nd3and_field", "_a___b_C"]);
1232		check_initialized_field_eq_cc!(&["_a1", "_a2", "_a3_"]);
1233	}
1234
1235	#[test]
1236	fn test01() {
1237		let mut v = json!({
1238			"a":1
1239		});
1240		let e = v.clone();
1241		retain_initialized_fields(&mut v, &[InitializedField::full("a")], String::default());
1242		assert_eq!(e, v);
1243	}
1244
1245	#[test]
1246	fn test02() {
1247		let mut v = json!({
1248			"a":1
1249		});
1250		retain_initialized_fields(&mut v, &[InitializedField::full("b")], String::default());
1251		assert_eq!(Value::Object(Default::default()), v);
1252	}
1253
1254	#[test]
1255	fn test03() {
1256		let mut v = json!({});
1257		retain_initialized_fields(&mut v, &[], String::default());
1258		assert_eq!(Value::Object(Default::default()), v);
1259	}
1260
1261	#[test]
1262	fn test04() {
1263		let mut v = json!({});
1264		retain_initialized_fields(&mut v, &[InitializedField::full("b")], String::default());
1265		assert_eq!(Value::Object(Default::default()), v);
1266	}
1267
1268	#[test]
1269	fn test05() {
1270		let mut v = json!({
1271			"a":1
1272		});
1273		retain_initialized_fields(&mut v, &[], String::default());
1274		assert_eq!(Value::Object(Default::default()), v);
1275	}
1276
1277	#[test]
1278	fn test06() {
1279		let mut v = json!({
1280			"a": {
1281				"b":1,
1282				"c":2
1283			}
1284		});
1285		retain_initialized_fields(&mut v, &[], String::default());
1286		assert_eq!(Value::Object(Default::default()), v);
1287	}
1288
1289	#[test]
1290	fn test07() {
1291		let mut v = json!({
1292			"a": {
1293				"b":1,
1294				"c":2
1295			}
1296		});
1297		retain_initialized_fields(&mut v, &[InitializedField::full("a.b")], String::default());
1298		assert_eq!(Value::Object(Default::default()), v);
1299	}
1300
1301	#[test]
1302	fn test08() {
1303		let mut v = json!({
1304			"a": {
1305				"b":1,
1306				"c":2
1307			}
1308		});
1309		let e = json!({
1310			"a": {
1311				"b":1,
1312			}
1313		});
1314		retain_initialized_fields(
1315			&mut v,
1316			&[InitializedField::partial("a"), InitializedField::full("a.b")],
1317			String::default(),
1318		);
1319		assert_eq!(e, v);
1320	}
1321
1322	#[test]
1323	fn test09() {
1324		let mut v = json!({
1325			"a": {
1326				"b":1,
1327				"c":2
1328			}
1329		});
1330		let e = json!({
1331			"a": {
1332				"b":1,
1333				"c":2,
1334			}
1335		});
1336		retain_initialized_fields(&mut v, &[InitializedField::full("a")], String::default());
1337		assert_eq!(e, v);
1338	}
1339}