scsys_core/macros/
gsw.rs

1/*
2    Appellation: gsw <module>
3    Contrib: @FL03
4*/
5
6/// The `gsw` macro generates getter and setter methods for the fields of a struct.
7///
8/// ### Usage
9///
10/// ```no_run
11///
12/// #[derive(Clone, Debug, Default)]
13/// pub struct Sample {
14///     pub(crate) a: usize,
15///     pub(crate) b: std::collections::HashMap<String, usize>,
16/// }
17///
18/// impl Sample {
19///     scsys_core::gsw! {
20///         a: usize,
21///     }
22///     scsys_core::gsw! {
23///         b: &std::collections::HashMap<String, usize>,
24///     }
25/// }
26/// #[test]
27/// fn _sampler() {
28///     let mut sample = Sample::default().with_a(10);
29///     assert_eq!(sample.a(), 10);
30///     assert_eq!(sample.a_mut(), &mut 10);
31///     assert_eq!(sample.set_a(20).a(), 20);
32/// }
33/// ```
34#[macro_export]
35macro_rules! gsw {
36    ($($name:ident: &$T:ty),* $(,)?) => {
37        $(
38            $crate::gsw!(@get $name: &$T);
39            $crate::gsw!(@get_mut $name: $T);
40            $crate::gsw!(@setter $name: $T);
41        )*
42    };
43    ($($name:ident: $T:ty),* $(,)?) => {
44        $(
45            $crate::gsw!(@get $name: $T);
46            $crate::gsw!(@get_mut $name: $T);
47            $crate::gsw!(@setter $name: $T);
48        )*
49    };
50    (@setter $name:ident: $T:ty) => {
51        $crate::gsw!(@set $name: $T);
52        $crate::gsw!(@with $name: $T);
53    };
54    (@get $name:ident: &$T:ty) => {
55        pub const fn $name(&self) -> &$T {
56            &self.$name
57        }
58    };
59    (@get $name:ident: $T:ty) => {
60        pub const fn $name(&self) -> $T {
61            self.$name
62        }
63    };
64    (@get_mut $name:ident: $T:ty) => {
65        paste::paste! {
66
67            pub fn [<$name _mut>] (&mut self) -> &mut $T {
68                &mut self.$name
69            }
70        }
71    };
72    (@set $name:ident: $T:ty) => {
73        paste::item! {
74            pub fn [<set_ $name>](&mut self, $name: $T) -> &mut Self {
75                self.$name = $name;
76                self
77            }
78        }
79    };
80    (@with $name:ident: $T:ty) => {
81        paste::item! {
82            pub fn [<with_ $name>] (self, $name: $T) -> Self {
83                Self {
84                    $name,
85                    ..self
86                }
87            }
88        }
89    };
90}