1use core::{fmt, ops::{Add, Sub,}};
2use saa_schema::saa_str_struct;
3use serde::{de, ser, Deserialize, Deserializer, Serialize};
4
5
6#[saa_str_struct]
7pub struct Uint64(#[cfg_attr(feature = "wasm", schemars(with = "String"))]pub(crate) u64);
8
9
10#[saa_str_struct]
11pub struct Uint128(#[cfg_attr(feature = "wasm", schemars(with = "String"))] pub(crate) u128);
12
13
14
15
16impl Uint64 {
17
18 pub const MAX: Self = Self(u64::MAX);
19 pub const MIN: Self = Self(u64::MIN);
20
21 pub const fn new(value: u64) -> Self {
25 Uint64(value)
26 }
27
28 #[inline]
30 pub const fn zero() -> Self {
31 Uint64(0)
32 }
33
34 #[inline]
36 pub const fn one() -> Self {
37 Self(1)
38 }
39
40 pub const fn u64(&self) -> u64 {
42 self.0
43 }
44
45
46 #[must_use = "this returns the result of the operation, without modifying the original"]
50 pub const fn strict_add(self, rhs: Self) -> Self {
51 match self.0.checked_add(rhs.u64()) {
52 None => panic!("attempt to add with overflow"),
53 Some(sum) => Self(sum),
54 }
55 }
56
57 #[must_use = "this returns the result of the operation, without modifying the original"]
61 pub const fn strict_sub(self, other: Self) -> Self {
62 match self.0.checked_sub(other.u64()) {
63 None => panic!("attempt to subtract with overflow"),
64 Some(diff) => Self(diff),
65 }
66 }
67
68}
69
70
71impl Uint128 {
72 pub const MAX: Self = Self(u128::MAX);
73 pub const MIN: Self = Self(u128::MIN);
74
75 pub const fn new(value: u128) -> Self {
79 Uint128(value)
80 }
81
82 #[inline]
84 pub const fn zero() -> Self {
85 Uint128(0)
86 }
87
88 #[inline]
90 pub const fn one() -> Self {
91 Self(1)
92 }
93
94 pub const fn u128(&self) -> u128 {
96 self.0
97 }
98
99 #[must_use = "this returns the result of the operation, without modifying the original"]
101 pub const fn to_be_bytes(self) -> [u8; 16] {
102 self.0.to_be_bytes()
103 }
104
105 #[must_use = "this returns the result of the operation, without modifying the original"]
107 pub const fn to_le_bytes(self) -> [u8; 16] {
108 self.0.to_le_bytes()
109 }
110
111 #[must_use = "this returns the result of the operation, without modifying the original"]
115 pub const fn strict_add(self, rhs: Self) -> Self {
116 match self.0.checked_add(rhs.u128()) {
117 None => panic!("attempt to add with overflow"),
118 Some(sum) => Self(sum),
119 }
120 }
121
122 #[must_use = "this returns the result of the operation, without modifying the original"]
126 pub const fn strict_sub(self, other: Self) -> Self {
127 match self.0.checked_sub(other.u128()) {
128 None => panic!("attempt to subtract with overflow"),
129 Some(diff) => Self(diff),
130 }
131 }
132
133}
134
135
136
137
138impl From<u64> for Uint64 {
140 fn from(val: u64) -> Self {
141 Uint64(val)
142 }
143}
144
145
146impl From<Uint64> for String {
147 fn from(original: Uint64) -> Self {
148 original.to_string()
149 }
150}
151
152impl From<Uint64> for u64 {
153 fn from(original: Uint64) -> Self {
154 original.0
155 }
156}
157
158impl fmt::Display for Uint64 {
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 self.0.fmt(f)
161 }
162}
163
164impl From<Uint128> for String {
165 fn from(original: Uint128) -> Self {
166 original.to_string()
167 }
168}
169
170impl From<Uint128> for u128 {
171 fn from(original: Uint128) -> Self {
172 original.0
173 }
174}
175
176impl fmt::Display for Uint128 {
177 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
178 self.0.fmt(f)
179 }
180}
181
182
183impl Add<Uint64> for Uint64 {
184 type Output = Self;
185
186 fn add(self, rhs: Self) -> Self {
187 self.strict_add(rhs)
188 }
189}
190
191impl Sub<Uint64> for Uint64 {
192 type Output = Self;
193
194 fn sub(self, rhs: Self) -> Self {
195 self.strict_sub(rhs)
196 }
197}
198
199impl Add<Uint128> for Uint128 {
200 type Output = Self;
201
202 fn add(self, rhs: Self) -> Self {
203 self.strict_add(rhs)
204 }
205}
206
207impl Sub<Uint128> for Uint128 {
208 type Output = Self;
209
210 fn sub(self, rhs: Self) -> Self {
211 self.strict_sub(rhs)
212 }
213}
214
215
216impl Serialize for Uint64 {
217 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
219 where
220 S: ser::Serializer,
221 {
222 serializer.serialize_str(&self.to_string())
223 }
224}
225
226impl<'de> Deserialize<'de> for Uint64 {
227 fn deserialize<D>(deserializer: D) -> Result<Uint64, D::Error>
229 where
230 D: Deserializer<'de>,
231 {
232 deserializer.deserialize_str(Uint64Visitor)
233 }
234}
235
236
237impl Serialize for Uint128 {
238 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
240 where
241 S: ser::Serializer,
242 {
243 serializer.serialize_str(&self.to_string())
244 }
245}
246
247impl<'de> Deserialize<'de> for Uint128 {
248 fn deserialize<D>(deserializer: D) -> Result<Uint128, D::Error>
250 where
251 D: Deserializer<'de>,
252 {
253 deserializer.deserialize_str(Uint128Visitor)
254 }
255}
256
257
258
259
260struct Uint64Visitor;
261
262impl<'de> de::Visitor<'de> for Uint64Visitor {
263 type Value = Uint64;
264
265 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
266 formatter.write_str("string-encoded integer")
267 }
268
269 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
270 where
271 E: de::Error,
272 {
273 match v.parse::<u64>() {
274 Ok(u) => Ok(Uint64(u)),
275 Err(e) => Err(E::custom(format!("invalid Uint64 '{v}' - {e}"))),
276 }
277 }
278}
279
280impl<A> core::iter::Sum<A> for Uint64
281where
282 Self: Add<A, Output = Self>,
283{
284 fn sum<I: Iterator<Item = A>>(iter: I) -> Self {
285 iter.fold(Self::zero(), Add::add)
286 }
287}
288
289
290struct Uint128Visitor;
291
292impl<'de> de::Visitor<'de> for Uint128Visitor {
293 type Value = Uint128;
294
295 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
296 formatter.write_str("string-encoded integer")
297 }
298
299 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
300 where
301 E: de::Error,
302 {
303 match v.parse::<u128>() {
304 Ok(u) => Ok(Uint128(u)),
305 Err(e) => Err(E::custom(format!("invalid Uint128 '{v}' - {e}"))),
306 }
307 }
308}