1macro_rules! map_value {
8 (from = $target:ty, handle_into = ($ival:ident) $into:block, handle_from = ($fval:ident) $from:block) => {
9 impl TryFrom<$crate::Value> for $target {
10 type Error = crate::Error;
11
12 fn try_from($fval: $crate::Value) -> Result<Self, Self::Error> $from
13 }
14
15 impl From<$target> for $crate::Value {
16 fn from($ival: $target) -> Self $into
17 }
18 };
19}
20
21macro_rules! map_type {
29 (Int, $source:ty) => {
30 map_type!(U8, $source);
31 map_type!(U16, $source);
32 map_type!(U32, $source);
33 map_type!(U64, $source);
34
35 map_type!(I8, $source);
36 map_type!(I16, $source);
37 map_type!(I32, $source);
38 map_type!(I64, $source);
39 };
40
41 ($target:ty, $source:ty) => {
42 impl TryFrom<$target> for $source {
43 type Error = crate::Error;
44 fn try_from(value: $target) -> Result<Self, Self::Error> {
45 Ok(Self::try_from(Value::from(value))?)
46 }
47 }
48 };
49}
50
51macro_rules! map_primitive {
60 (from = $source:ty, primitive = $primitive:ty) => {
61 #[allow(clippy::from_over_into)]
62 impl Into<$primitive> for $source {
63 fn into(self) -> $primitive {
64 self.0
65 }
66 }
67
68 impl From<$primitive> for $source {
69 fn from(value: $primitive) -> Self {
70 <$source>::new(value)
71 }
72 }
73
74 impl From<$primitive> for $crate::Value {
75 fn from(value: $primitive) -> Self {
76 <$source>::new(value).into()
77 }
78 }
79
80 #[allow(clippy::from_over_into)]
81 impl TryInto<$primitive> for $crate::Value {
82 type Error = crate::Error;
83 fn try_into(self) -> Result<$primitive, Self::Error> {
84 let value: $source = self.try_into()?;
85 Ok(value.into())
86 }
87 }
88 };
89}
90
91macro_rules! impl_value {
95 ($own_type:ty, $inner_type:ty, $to_string:expr, $debug:expr) => {
96 impl $crate::ValueTrait for $own_type {
97 type Inner = $inner_type;
98
99 fn new(inner: $inner_type) -> Self {
100 Self(inner)
101 }
102
103 fn inner(&self) -> &$inner_type {
104 &self.0
105 }
106
107 fn inner_mut(&mut self) -> &mut $inner_type {
108 &mut self.0
109 }
110
111 fn into_inner(self) -> $inner_type {
112 self.0
113 }
114 }
115
116 map_primitive!(from = $own_type, primitive = $inner_type);
117
118 impl std::fmt::Display for $own_type {
119 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
120 write!(f, "{}", $to_string(self))
121 }
122 }
123
124 impl std::fmt::Debug for $own_type {
125 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126 $debug(self, f)
127 }
128 }
129 };
130 ($own_type:ty, $inner_type:ty, $to_string:expr) => {
131 impl_value!(
132 $own_type,
133 $inner_type,
134 $to_string,
135 |this: &Self, f: &mut std::fmt::Formatter<'_>| { write!(f, "{}", $to_string(this)) }
136 );
137 };
138}
139
140macro_rules! overload_operator {
141 ($type:ident, arithmetic) => {
142 overload_operator!($type, add);
143 overload_operator!($type, sub);
144 overload_operator!($type, mul);
145 overload_operator!($type, div);
146 overload_operator!($type, rem);
147 overload_operator!($type, neg);
148 };
149
150 ($type:ident, add) => {
151 impl std::ops::Add for $type {
152 type Output = Result<Self, crate::Error>;
153 fn add(self, rhs: Self) -> Self::Output {
154 Self::arithmetic_op(self, rhs, ArithmeticOperation::Add)
155 }
156 }
157 };
158
159 ($type:ident, sub) => {
160 impl std::ops::Sub for $type {
161 type Output = Result<Self, crate::Error>;
162 fn sub(self, rhs: Self) -> Self::Output {
163 Self::arithmetic_op(self, rhs, ArithmeticOperation::Subtract)
164 }
165 }
166 };
167
168 ($type:ident, mul) => {
169 impl std::ops::Mul for $type {
170 type Output = Result<Self, crate::Error>;
171 fn mul(self, rhs: Self) -> Self::Output {
172 Self::arithmetic_op(self, rhs, ArithmeticOperation::Multiply)
173 }
174 }
175 };
176
177 ($type:ident, div) => {
178 impl std::ops::Div for $type {
179 type Output = Result<Self, crate::Error>;
180 fn div(self, rhs: Self) -> Self::Output {
181 Self::arithmetic_op(self, rhs, ArithmeticOperation::Divide)
182 }
183 }
184 };
185
186 ($type:ident, rem) => {
187 impl std::ops::Rem for $type {
188 type Output = Result<Self, crate::Error>;
189 fn rem(self, rhs: Self) -> Self::Output {
190 Self::arithmetic_op(self, rhs, ArithmeticOperation::Modulo)
191 }
192 }
193 };
194
195 ($type:ident, neg) => {
196 impl std::ops::Neg for $type {
197 type Output = Result<Self, crate::Error>;
198 fn neg(self) -> Self::Output {
199 Self::arithmetic_neg(self)
200 }
201 }
202 };
203
204 ($type:ident, bitwise) => {
206 overload_operator!($type, bitand);
207 overload_operator!($type, bitor);
208 overload_operator!($type, bitxor);
209 overload_operator!($type, shl);
210 overload_operator!($type, shr);
211 };
212
213 ($type:ident, bitand) => {
214 impl std::ops::BitAnd for $type {
215 type Output = Result<Self, crate::Error>;
216 fn bitand(self, rhs: Self) -> Self::Output {
217 Self::bitwise_op(self, rhs, BitwiseOperation::And)
218 }
219 }
220 };
221
222 ($type:ident, bitor) => {
223 impl std::ops::BitOr for $type {
224 type Output = Result<Self, crate::Error>;
225 fn bitor(self, rhs: Self) -> Self::Output {
226 Self::bitwise_op(self, rhs, BitwiseOperation::Or)
227 }
228 }
229 };
230
231 ($type:ident, bitxor) => {
232 impl std::ops::BitXor for $type {
233 type Output = Result<Self, crate::Error>;
234 fn bitxor(self, rhs: Self) -> Self::Output {
235 Self::bitwise_op(self, rhs, BitwiseOperation::Xor)
236 }
237 }
238 };
239
240 ($type:ident, shl) => {
241 impl std::ops::Shl for $type {
242 type Output = Result<Self, crate::Error>;
243 fn shl(self, rhs: Self) -> Self::Output {
244 Self::bitwise_op(self, rhs, BitwiseOperation::LeftShift)
245 }
246 }
247 };
248
249 ($type:ident, shr) => {
250 impl std::ops::Shr for $type {
251 type Output = Result<Self, crate::Error>;
252 fn shr(self, rhs: Self) -> Self::Output {
253 Self::bitwise_op(self, rhs, BitwiseOperation::RightShift)
254 }
255 }
256 };
257
258 ($type:ident, bool_not) => {
260 impl std::ops::Not for $type {
261 type Output = Result<Value, crate::Error>;
262 fn not(self) -> Self::Output {
263 Self::boolean_not(self)
264 }
265 }
266 };
267
268 ($type:ident, deref) => {
270 impl std::ops::Deref for $type {
271 type Target = <$type as ValueTrait>::Inner;
272 fn deref(&self) -> &Self::Target {
273 self.inner()
274 }
275 }
276
277 impl std::ops::DerefMut for $type {
278 fn deref_mut(&mut self) -> &mut Self::Target {
279 self.inner_mut()
280 }
281 }
282 };
283}