contained_core/macros/
wrapper.rs

1/*
2    Appellation: wrapper <module>
3    Contrib: @FL03
4*/
5
6#[macro_export]
7macro_rules! wrapper {
8    ($($S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?;),* $(,)?) => {
9        $(
10            $crate::wrapper!(@impl $S($vis $T) $(where $($rest)*)?;);
11        )*
12    };
13    (@impl
14        #[derive($($derive:ident),*)]
15        $S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?;
16    ) => {
17        #[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd, $($derive),*)]
18        #[cfg_attr(
19            feature = "serde",
20            derive(serde::Deserialize, serde::Serialize),
21            serde(default, transparent),
22        )]
23        #[repr(transparent)]
24        pub struct $S<$T>($vis $T) $(where $($rest)*)?;
25
26        impl<$T> $S<$T> {
27            /// returns a new instance with the given value
28            pub const fn new(value: $T) -> Self {
29                Self(value)
30            }
31            /// returns an immutable reference to the inner value
32            pub const fn get(&self) -> &$T {
33                &self.0
34            }
35            /// returns a mutable reference to the inner value
36            pub const fn get_mut(&mut self) -> &mut $T {
37                &mut self.0
38            }
39            /// consumes the current instance to return the inner value
40            #[inline]
41            pub fn into_inner(self) -> $T {
42                self.0
43            }
44            /// applies the given function to the inner value and returns a new instance with
45            /// the result
46            #[inline]
47            pub fn map<R, F>(self, f: F) -> $S<R>
48            where
49                F: FnOnce($T) -> R,
50            {
51                $S(f(self.0))
52            }
53            /// [`replace`](core::mem::replace) the inner value with the given, returning the previous value
54            pub const fn replace(&mut self, value: $T) -> $T {
55                ::core::mem::replace(self.get_mut(), value)
56            }
57            /// set the inner value, in-place
58            #[inline]
59            pub fn set(&mut self, value: $T) {
60                *self.get_mut() = value;
61            }
62            /// [`swap`](core::mem::swap) the inner value with that of another instance of the same type
63            pub const fn swap(&mut self, other: &mut Self) {
64                ::core::mem::swap(self.get_mut(), other.get_mut());
65            }
66            /// [`take`](core::mem::take) the inner value, leaving a default in its place
67            #[inline]
68            pub fn take(&mut self) -> $T
69            where
70                $T: Default,
71            {
72                ::core::mem::take(self.get_mut())
73            }
74            /// consumes the current instance to create another with the given value
75            pub fn with<_U>(self, value: _U) -> $S<_U> {
76                $S::new(value)
77            }
78            /// captures a referenced value in a new instance
79            pub fn view(&self) -> $S<&$T> {
80                $S::new(self.get())
81            }
82            /// captures a mutable reference to the inner value
83            pub fn view_mut(&mut self) -> $S<&mut $T> {
84                $S::new(self.get_mut())
85            }
86        }
87
88        impl<$T> AsRef<$T> for $S<$T> {
89            fn as_ref(&self) -> &$T {
90                self.get()
91            }
92        }
93
94        impl<$T> AsMut<$T> for $S<$T> {
95            fn as_mut(&mut self) -> &mut $T {
96                self.get_mut()
97            }
98        }
99
100        impl<$T> ::core::borrow::Borrow<$T> for $S<$T> {
101            fn borrow(&self) -> &$T {
102                self.get()
103            }
104        }
105
106        impl<$T> ::core::borrow::BorrowMut<$T> for $S<$T> {
107            fn borrow_mut(&mut self) -> &mut $T {
108                self.get_mut()
109            }
110        }
111
112        impl<$T> ::core::ops::Deref for $S<$T> {
113            type Target = $T;
114
115            fn deref(&self) -> &Self::Target {
116                self.get()
117            }
118        }
119
120        impl<$T> ::core::ops::DerefMut for $S<$T> {
121            fn deref_mut(&mut self) -> &mut Self::Target {
122                self.get_mut()
123            }
124        }
125
126        impl<$T> From<$T> for $S<$T> {
127            fn from(value: $T) -> Self {
128                Self(value)
129            }
130        }
131    };
132}