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