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}