scsys_core/macros/
gsw.rs

1/*
2    Appellation: gsw <module>
3    Contrib: @FL03
4*/
5/// The `gsw` macro generates getter and setter methods for the fields of a struct. At the
6/// moment, the macro can handle any type; for types that implement the [`Copy`] trait, simply
7/// drop the `&` to the left of each type.
8///
9/// **Note**: make sure that
10///
11/// ### Usage
12///
13/// ```rust
14/// use scsys_core::gsw;
15///
16/// #[derive(Clone, Debug, Default)]
17/// pub struct Sample<T> {
18///     pub(crate) a: usize,
19///     pub(crate) b: f32,
20///     pub(crate) store: Vec<u8>,
21///     pub(crate) c:T,
22///
23/// }
24///
25/// impl<T> Sample<T> {
26///     gsw! {
27///         a: usize,
28///         b: f32,
29///     }
30///     gsw! {
31///         c: &T,
32///         store: &Vec<u8>,
33///     }
34/// }
35///
36/// #[test]
37/// fn test_sample_gsw_impls() {
38///     let mut sample = Sample::<&str>::default().with_a(10).with_store(vec![1, 2, 3]);
39///     sample.set_b(3.14).set_c("hello");
40///     assert_eq!(sample.a(), 10);
41///     assert_eq!(sample.b(), 3.14);
42///     assert_eq!(sample.c(), "hello");
43///     assert_eq!(sample.store(), &vec![1, 2, 3]);
44///     sample.c_mut().push(u8::MAX);
45///     assert!(sample.store().last() == Some(&u8::MAX));
46/// }
47/// ```
48#[macro_export]
49macro_rules! gsw {
50    ($($name:ident: &$T:ty),* $(,)?) => {
51        $(
52            $crate::gsw!(@get $name: &$T);
53            $crate::gsw!(@get_mut $name: $T);
54            $crate::gsw!(@setter $name: $T);
55        )*
56    };
57    ($($name:ident: $T:ty),* $(,)?) => {
58        $(
59            $crate::gsw!(@get $name: $T);
60            $crate::gsw!(@get_mut $name: $T);
61            $crate::gsw!(@setter $name: $T);
62        )*
63    };
64    (@get $name:ident: &$T:ty) => {
65        pub const fn $name(&self) -> &$T {
66            &self.$name
67        }
68    };
69    (@get $name:ident: $T:ty) => {
70        pub const fn $name(&self) -> $T {
71            self.$name
72        }
73    };
74    (@get_mut $name:ident: $T:ty) => {
75        paste::paste! {
76            pub const fn [<$name _mut>] (&mut self) -> &mut $T {
77                &mut self.$name
78            }
79        }
80    };
81    (@setter $name:ident: $T:ty) => {
82        paste::paste! {
83            pub fn [<set_ $name>](&mut self, $name: $T) -> &mut Self {
84                self.$name = $name;
85                self
86            }
87
88            pub fn [<with_ $name>] (self, $name: $T) -> Self {
89                Self {
90                    $name,
91                    ..self
92                }
93            }
94        }
95    };
96}
97
98#[macro_export]
99macro_rules! get_field {
100    ($($name:ident: &$T:ty),* $(,)?) => {
101        $(
102            $crate::gsw!(@get $name: &$T);
103            $crate::gsw!(@get_mut $name: $T);
104            $crate::gsw!(@setter $name: $T);
105        )*
106    };
107    ($($name:ident: $T:ty),* $(,)?) => {
108        $(
109            $crate::gsw!(@get $name: $T);
110            $crate::gsw!(@get_mut $name: $T);
111            $crate::gsw!(@setter $name: $T);
112        )*
113    };
114
115    (@getter $name:ident: &$T:ty) => {
116        pub const fn $name(&self) -> &$T {
117            &self.$name
118        }
119    };
120    (@getter $name:ident: $T:ty) => {
121        pub const fn $name(&self) -> $T {
122            self.$name
123        }
124    };
125    (@get_mut $name:ident: $T:ty) => {
126        paste::paste! {
127            pub const fn [<$name _mut>] (&mut self) -> &mut $T {
128                &mut self.$name
129            }
130        }
131    };
132    (@get $name:ident: &$T:ty) => {
133        pub const fn $name(&self) -> &$T {
134            &self.$name
135        }
136    };
137    (@get $name:ident: $T:ty) => {
138        pub const fn $name(&self) -> $T {
139            self.$name
140        }
141    };
142}