scsys_core/macros/
wrapper.rs

1/*
2    Appellation: wrapper <module>
3    Contrib: @FL03
4*/
5
6///
7///
8/// ### Example
9///
10/// ```rust
11/// use scsys_core::fmt_wrapper;
12///
13/// pub struct Sample<T>(pub T);
14///
15/// fmt_wrapper!(Sample<Q>(Binary, Debug, Display, LowerHex, UpperHex, LowerExp, UpperExp, Pointer));
16/// ```
17#[macro_export]
18macro_rules! fmt_wrapper {
19    ($s:ident<$T:ident> ($($trait:ident),* $(,)?)) => {
20        $(
21            $crate::fmt_wrapper!(@impl $s::<$T>::$trait);
22        )*
23    };
24    ($s:ident<$T:ident>.$field:ident {$($trait:ident),* $(,)?}) => {
25        $(
26            $crate::fmt_wrapper!(@impl $s::<$T>::$trait.$field);
27        )*
28    };
29
30    (@impl $s:ident::<$T:ident>::$trait:ident) => {
31        $crate::fmt_wrapper!(@impl #[field(0)] $s::<$T>::$trait);
32    };
33    (@impl #[field($field:tt)] $s:ident::<$T:ident>::$trait:ident) => {
34        impl<$T> ::core::fmt::$trait for $s<$T>
35        where
36        $T: ::core::fmt::$trait
37        {
38            fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
39                ::core::fmt::$trait::fmt(
40                    &self.$field,
41                    f,
42                )
43            }
44        }
45    };
46}
47
48#[macro_export]
49macro_rules! wrapper {
50    ($($S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?;),* $(,)?) => {
51        $(
52            $crate::wrapper!(@impl $S($vis $T) $(where $($rest)*)?;);
53        )*
54    };
55    (@impl
56        #[derive($($derive:ident),*)]
57        $S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?;
58    ) => {
59        #[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd, $($derive),*)]
60        #[cfg_attr(
61            feature = "serde",
62            derive(serde::Deserialize, serde::Serialize),
63            serde(default, transparent),
64        )]
65        #[repr(transparent)]
66        pub struct $S<$T>($vis $T) $(where $($rest)*)?;
67
68        impl<$T> $S<$T> {
69            /// returns a new instance initialized with the default value
70            pub fn new() -> Self
71            where
72                $T: Default,
73            {
74                Self($T::default())
75            }
76            /// returns a new instance with the given value
77            pub fn from_value(value: $T) -> Self {
78                Self(value)
79            }
80            /// returns an immutable reference to the inner value
81            pub const fn get(&self) -> &$T {
82                &self.0
83            }
84            /// returns a mutable reference to the inner value
85            pub const fn get_mut(&mut self) -> &mut $T {
86                &mut self.0
87            }
88            /// consumes the current instance to return the inner value
89            pub fn into_inner(self) -> $T {
90                self.0
91            }
92            /// applies the given function to the inner value and returns a new instance with
93            /// the result
94            pub fn map<R, F>(self, f: F) -> $S<R>
95            where
96                F: FnOnce($T) -> R,
97            {
98                $S(f(self.0))
99            }
100            /// uses the [`replace`](core::mem::replace) method to update and return the inner value
101            pub fn replace(&mut self, value: $T) -> $T {
102                core::mem::replace(self.get_mut(), value)
103            }
104            /// update the innerstate before returing a mutable reference to the wrapper
105            pub fn set(&mut self, value: $T) -> &mut Self {
106                *self.get_mut() = value;
107                self
108            }
109            /// uses the [`take`](core::mem::take) method to replace the inner value with the default
110            /// value to return its previous value
111            pub fn take(&mut self) -> $T
112            where
113                $T: Default,
114            {
115                core::mem::take(self.get_mut())
116            }
117            /// consumes the current instance to create another with the given value
118            pub fn with(self, value: $T) -> Self {
119                Self(value)
120            }
121            /// captures a referenced value in a new instance
122            pub fn view(&self) -> $S<&$T> {
123                $S(self.get())
124            }
125            /// captures a mutable reference to the inner value
126            pub fn view_mut(&mut self) -> $S<&mut $T> {
127                $S(self.get_mut())
128            }
129        }
130
131        impl<$T> AsRef<$T> for $S<$T> {
132            fn as_ref(&self) -> &$T {
133                self.get()
134            }
135        }
136
137        impl<$T> AsMut<$T> for $S<$T> {
138            fn as_mut(&mut self) -> &mut $T {
139                self.get_mut()
140            }
141        }
142
143        impl<$T> ::core::borrow::Borrow<$T> for $S<$T> {
144            fn borrow(&self) -> &$T {
145                self.get()
146            }
147        }
148
149        impl<$T> ::core::borrow::BorrowMut<$T> for $S<$T> {
150            fn borrow_mut(&mut self) -> &mut $T {
151                self.get_mut()
152            }
153        }
154
155        impl<$T> ::core::ops::Deref for $S<$T> {
156            type Target = $T;
157
158            fn deref(&self) -> &Self::Target {
159                self.get()
160            }
161        }
162
163        impl<$T> ::core::ops::DerefMut for $S<$T> {
164            fn deref_mut(&mut self) -> &mut Self::Target {
165                self.get_mut()
166            }
167        }
168
169        impl<$T> From<$T> for $S<$T> {
170            fn from(value: $T) -> Self {
171                Self(value)
172            }
173        }
174    };
175}