Skip to main content

proto_types/
num_wrappers.rs

1use crate::*;
2
3use core::{
4	borrow::{Borrow, BorrowMut},
5	cmp::Ordering,
6	ops::*,
7};
8use num_traits::{Num, One, Zero};
9
10/// Trait for numbers that represent protobuf integer types, such as `sint32` or `fixed64`.
11pub trait ProtoIntWrapper:
12	Num
13	+ Clone
14	+ Copy
15	+ Display
16	+ Debug
17	+ Eq
18	+ Ord
19	+ Hash
20	+ Default
21	+ Add<Self::Target>
22	+ Sub<Self::Target>
23	+ Mul<Self::Target>
24	+ Div<Self::Target>
25	+ Rem<Self::Target>
26	+ Into<Self::Target>
27	+ Borrow<Self::Target>
28	+ BorrowMut<Self::Target>
29	+ AsRef<Self::Target>
30	+ PartialOrd<Self::Target>
31{
32	type Target: Num + Clone + Copy + Display + Debug + Eq + Ord + Hash + Default;
33
34	/// The name of the associated type (i.e. "sfixed32")
35	fn name() -> &'static str;
36}
37
38macro_rules! impl_wrapper {
39	($name:ident, $target:ty) => {
40		#[doc = "Wrapper struct that represents the protobuf type `"]
41		#[doc = stringify!($name)]
42		#[doc = "`. It implements [`ProtoIntWrapper`]."]
43		#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
44		pub struct $name(pub $target);
45
46		impl ProtoIntWrapper for $name {
47			type Target = $target;
48
49			#[inline]
50			fn name() -> &'static str {
51				paste::paste! {
52				  stringify!([< $name:lower >])
53				}
54			}
55		}
56
57		impl Display for $name {
58			fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
59				write!(f, "{}", self.0)
60			}
61		}
62
63		impl PartialOrd<$target> for $name {
64			#[inline]
65			fn partial_cmp(
66				&self,
67				other: &$target,
68			) -> core::prelude::v1::Option<core::cmp::Ordering> {
69				Some(self.0.cmp(other))
70			}
71		}
72
73		impl PartialOrd<$name> for $target {
74			#[inline]
75			fn partial_cmp(&self, other: &$name) -> core::prelude::v1::Option<core::cmp::Ordering> {
76				other.partial_cmp(self).map(Ordering::reverse)
77			}
78		}
79
80		impl core::ops::Deref for $name {
81			type Target = $target;
82			#[inline]
83			fn deref(&self) -> &Self::Target {
84				&self.0
85			}
86		}
87
88		impl core::cmp::PartialEq<$target> for $name {
89			#[inline]
90			fn eq(&self, other: &$target) -> bool {
91				self.0 == *other
92			}
93		}
94
95		impl core::cmp::PartialEq<$name> for $target {
96			#[inline]
97			fn eq(&self, other: &$name) -> bool {
98				other == self
99			}
100		}
101
102		impl core::ops::Add for $name {
103			type Output = Self;
104
105			#[inline]
106			fn add(self, rhs: Self) -> Self::Output {
107				Self(self.0 + rhs.0)
108			}
109		}
110
111		impl core::ops::Add<$target> for $name {
112			type Output = $target;
113
114			#[inline]
115			fn add(self, rhs: $target) -> Self::Output {
116				self.0 + rhs
117			}
118		}
119
120		impl Zero for $name {
121			#[inline]
122			fn zero() -> Self {
123				Self(0)
124			}
125
126			#[inline]
127			fn is_zero(&self) -> bool {
128				self.0 == 0
129			}
130		}
131
132		impl One for $name {
133			#[inline]
134			fn one() -> Self {
135				Self(1)
136			}
137		}
138
139		impl core::ops::Mul for $name {
140			type Output = Self;
141
142			#[inline]
143			fn mul(self, rhs: Self) -> Self::Output {
144				Self(self.0 * rhs.0)
145			}
146		}
147
148		impl core::ops::Mul<$target> for $name {
149			type Output = $target;
150
151			#[inline]
152			fn mul(self, rhs: $target) -> Self::Output {
153				self.0 * rhs
154			}
155		}
156
157		impl core::ops::Div for $name {
158			type Output = Self;
159
160			#[inline]
161			fn div(self, rhs: Self) -> Self::Output {
162				Self(self.0 / rhs.0)
163			}
164		}
165
166		impl core::ops::Div<$target> for $name {
167			type Output = $target;
168
169			#[inline]
170			fn div(self, rhs: $target) -> Self::Output {
171				self.0 / rhs
172			}
173		}
174
175		impl core::ops::Rem for $name {
176			type Output = Self;
177
178			#[inline]
179			fn rem(self, rhs: Self) -> Self::Output {
180				Self(self.0 % rhs.0)
181			}
182		}
183
184		impl core::ops::Rem<$target> for $name {
185			type Output = $target;
186
187			#[inline]
188			fn rem(self, rhs: $target) -> Self::Output {
189				self.0 % rhs
190			}
191		}
192
193		impl core::ops::Sub for $name {
194			type Output = Self;
195
196			#[inline]
197			fn sub(self, rhs: Self) -> Self::Output {
198				Self(self.0 - rhs.0)
199			}
200		}
201
202		impl core::ops::Sub<$target> for $name {
203			type Output = $target;
204
205			#[inline]
206			fn sub(self, rhs: $target) -> Self::Output {
207				self.0 - rhs
208			}
209		}
210
211		impl core::ops::DerefMut for $name {
212			#[inline]
213			fn deref_mut(&mut self) -> &mut Self::Target {
214				&mut self.0
215			}
216		}
217
218		impl Num for $name {
219			type FromStrRadixErr = <$target as num_traits::Num>::FromStrRadixErr;
220
221			#[inline]
222			fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
223				Ok(Self(<$target>::from_str_radix(str, radix)?))
224			}
225		}
226
227		impl From<$name> for $target {
228			#[inline]
229			fn from(value: $name) -> $target {
230				value.0
231			}
232		}
233
234		impl From<$target> for $name {
235			#[inline]
236			fn from(value: $target) -> $name {
237				Self(value)
238			}
239		}
240
241		impl AsRef<$target> for $name {
242			#[inline]
243			fn as_ref(&self) -> &$target {
244				self
245			}
246		}
247
248		impl core::borrow::Borrow<$target> for $name {
249			#[inline]
250			fn borrow(&self) -> &$target {
251				self
252			}
253		}
254
255		impl core::borrow::BorrowMut<$target> for $name {
256			#[inline]
257			fn borrow_mut(&mut self) -> &mut $target {
258				self
259			}
260		}
261	};
262}
263
264impl_wrapper!(Sint64, i64);
265impl_wrapper!(Sint32, i32);
266impl_wrapper!(Sfixed64, i64);
267impl_wrapper!(Sfixed32, i32);
268impl_wrapper!(Fixed64, u64);
269impl_wrapper!(Fixed32, u32);