tycho_types/num/
mod.rs

1//! Integer types used in blockchain models.
2
3use std::num::NonZeroU8;
4
5pub use self::varuint248::VarUint248;
6use crate::cell::*;
7use crate::error::{Error, ParseIntError};
8use crate::util::unlikely;
9
10mod varuint248;
11
12macro_rules! impl_serde {
13    ($ident:ident, $inner: ty) => {
14        #[cfg(feature = "serde")]
15        impl serde::Serialize for $ident {
16            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
17            where
18                S: serde::Serializer,
19            {
20                self.0.serialize(serializer)
21            }
22        }
23
24        #[cfg(feature = "serde")]
25        impl<'de> serde::Deserialize<'de> for $ident {
26            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
27            where
28                D: serde::Deserializer<'de>,
29            {
30                use serde::de::{Error, Unexpected};
31
32                struct Expected;
33
34                impl serde::de::Expected for Expected {
35                    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36                        f.write_str(stringify!($ident))
37                    }
38                }
39
40                let res = Self::new(ok!(<$inner>::deserialize(deserializer)));
41                if res.is_valid() {
42                    Ok(res)
43                } else {
44                    Err(D::Error::invalid_type(
45                        Unexpected::Other("big number"),
46                        &Expected,
47                    ))
48                }
49            }
50        }
51    };
52}
53
54macro_rules! impl_ops {
55    ($ident:ident, $inner:ty) => {
56        impl From<$ident> for $inner {
57            #[inline]
58            fn from(value: $ident) -> Self {
59                value.0
60            }
61        }
62
63        impl TryFrom<$inner> for $ident {
64            type Error = ParseIntError;
65
66            #[inline]
67            fn try_from(inner: $inner) -> Result<Self, Self::Error> {
68                let result = Self::new(inner);
69                if result.is_valid() {
70                    Ok(result)
71                } else {
72                    Err(ParseIntError::Overflow)
73                }
74            }
75        }
76
77        #[cfg(feature = "bigint")]
78        impl From<$ident> for num_bigint::BigInt {
79            #[inline]
80            fn from(value: $ident) -> Self {
81                Self::from(value.0)
82            }
83        }
84
85        #[cfg(feature = "bigint")]
86        impl From<$ident> for num_bigint::BigUint {
87            #[inline]
88            fn from(value: $ident) -> Self {
89                Self::from(value.0)
90            }
91        }
92
93        impl std::str::FromStr for $ident {
94            type Err = ParseIntError;
95
96            fn from_str(s: &str) -> Result<Self, Self::Err> {
97                match std::str::FromStr::from_str(s) {
98                    Ok(inner) => {
99                        let result = Self::new(inner);
100                        if result.is_valid() {
101                            Ok(result)
102                        } else {
103                            Err(ParseIntError::Overflow)
104                        }
105                    }
106                    Err(e) => Err(ParseIntError::InvalidString(e)),
107                }
108            }
109        }
110
111        impl PartialEq<$inner> for $ident {
112            #[inline]
113            fn eq(&self, other: &$inner) -> bool {
114                self.0 == *other
115            }
116        }
117
118        impl PartialEq<$ident> for $inner {
119            #[inline]
120            fn eq(&self, other: &$ident) -> bool {
121                *self == other.0
122            }
123        }
124
125        impl std::fmt::Display for $ident {
126            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127                self.0.fmt(f)
128            }
129        }
130
131        impl std::fmt::Binary for $ident {
132            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133                std::fmt::Binary::fmt(&self.0, f)
134            }
135        }
136
137        impl std::fmt::LowerHex for $ident {
138            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139                std::fmt::LowerHex::fmt(&self.0, f)
140            }
141        }
142
143        impl std::fmt::UpperHex for $ident {
144            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
145                std::fmt::UpperHex::fmt(&self.0, f)
146            }
147        }
148
149        impl std::ops::Add for $ident {
150            type Output = Self;
151
152            #[inline]
153            fn add(mut self, rhs: Self) -> Self::Output {
154                self.0 += rhs.0;
155                self
156            }
157        }
158
159        impl std::ops::Add<$inner> for $ident {
160            type Output = Self;
161
162            #[inline]
163            fn add(mut self, rhs: $inner) -> Self::Output {
164                self.0 += rhs;
165                self
166            }
167        }
168
169        impl std::ops::AddAssign for $ident {
170            #[inline]
171            fn add_assign(&mut self, rhs: Self) {
172                self.0 += rhs.0;
173            }
174        }
175
176        impl std::ops::AddAssign<$inner> for $ident {
177            fn add_assign(&mut self, rhs: $inner) {
178                self.0 += rhs;
179            }
180        }
181
182        impl std::ops::Sub for $ident {
183            type Output = Self;
184
185            #[inline]
186            fn sub(mut self, rhs: Self) -> Self::Output {
187                self.0 -= rhs.0;
188                self
189            }
190        }
191
192        impl std::ops::Sub<$inner> for $ident {
193            type Output = Self;
194
195            #[inline]
196            fn sub(mut self, rhs: $inner) -> Self::Output {
197                self.0 -= rhs;
198                self
199            }
200        }
201
202        impl std::ops::SubAssign for $ident {
203            #[inline]
204            fn sub_assign(&mut self, rhs: Self) {
205                self.0 -= rhs.0;
206            }
207        }
208
209        impl std::ops::SubAssign<$inner> for $ident {
210            #[inline]
211            fn sub_assign(&mut self, rhs: $inner) {
212                self.0 -= rhs;
213            }
214        }
215
216        impl std::ops::Mul for $ident {
217            type Output = Self;
218
219            #[inline]
220            fn mul(mut self, rhs: Self) -> Self::Output {
221                self.0 *= rhs.0;
222                self
223            }
224        }
225
226        impl std::ops::Mul<$inner> for $ident {
227            type Output = Self;
228
229            #[inline]
230            fn mul(mut self, rhs: $inner) -> Self::Output {
231                self.0 *= rhs;
232                self
233            }
234        }
235
236        impl std::ops::MulAssign for $ident {
237            #[inline]
238            fn mul_assign(&mut self, rhs: Self) {
239                self.0 *= rhs.0;
240            }
241        }
242
243        impl std::ops::MulAssign<$inner> for $ident {
244            #[inline]
245            fn mul_assign(&mut self, rhs: $inner) {
246                self.0 *= rhs;
247            }
248        }
249
250        impl std::ops::Div for $ident {
251            type Output = Self;
252
253            #[inline]
254            fn div(mut self, rhs: Self) -> Self::Output {
255                self.0 /= rhs.0;
256                self
257            }
258        }
259
260        impl std::ops::Div<$inner> for $ident {
261            type Output = Self;
262
263            #[inline]
264            fn div(mut self, rhs: $inner) -> Self::Output {
265                self.0 /= rhs;
266                self
267            }
268        }
269
270        impl std::ops::DivAssign for $ident {
271            #[inline]
272            fn div_assign(&mut self, rhs: Self) {
273                self.0 /= rhs.0;
274            }
275        }
276
277        impl std::ops::DivAssign<$inner> for $ident {
278            #[inline]
279            fn div_assign(&mut self, rhs: $inner) {
280                self.0 /= rhs;
281            }
282        }
283
284        impl std::ops::Shr<u8> for $ident {
285            type Output = Self;
286
287            #[inline]
288            fn shr(mut self, rhs: u8) -> Self::Output {
289                self.0 >>= rhs;
290                self
291            }
292        }
293
294        impl std::ops::ShrAssign<u8> for $ident {
295            #[inline]
296            fn shr_assign(&mut self, rhs: u8) {
297                self.0 >>= rhs;
298            }
299        }
300
301        impl std::ops::Shl<u8> for $ident {
302            type Output = Self;
303
304            #[inline]
305            fn shl(mut self, rhs: u8) -> Self::Output {
306                self.0 <<= rhs;
307                self
308            }
309        }
310
311        impl std::ops::ShlAssign<u8> for $ident {
312            #[inline]
313            fn shl_assign(&mut self, rhs: u8) {
314                self.0 <<= rhs;
315            }
316        }
317    };
318}
319
320macro_rules! impl_var_uints {
321    ($($(#[doc = $doc:expr])* $vis:vis struct $ident:ident($inner:ty[..$max_bytes:literal]);)*) => {
322        $(
323            impl_var_uints!{@impl $(#[doc = $doc])* $vis $ident $inner, $max_bytes}
324        )*
325    };
326
327    (@impl $(#[doc = $doc:expr])* $vis:vis $ident:ident $inner:ty, $max_bytes:literal) => {
328        $(#[doc = $doc])*
329        #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
330        #[repr(transparent)]
331        $vis struct $ident($inner);
332
333        impl $ident {
334            /// The additive identity for this integer type, i.e. `0`.
335            pub const ZERO: Self = $ident(0);
336
337            /// The multiplicative identity for this integer type, i.e. `1`.
338            pub const ONE: Self = $ident(1);
339
340            /// The smallest value that can be represented by this integer type.
341            pub const MIN: Self = $ident(0);
342
343            /// The largest value that can be represented by this integer type.
344            pub const MAX: Self = $ident(((1 as $inner) << ($max_bytes * 8)) - 1);
345
346            /// The number of data bits that the length occupies.
347            pub const LEN_BITS: u16 = 8 - ($max_bytes as u8).leading_zeros() as u16;
348
349            /// The maximum number of data bits that this struct occupies.
350            pub const MAX_BITS: u16 = Self::LEN_BITS + $max_bytes * 8;
351
352            /// Creates a new integer value from a primitive integer.
353            #[inline]
354            pub const fn new(value: $inner) -> Self {
355                Self(value)
356            }
357
358            /// Converts integer into an underlying primitive integer.
359            #[inline]
360            pub const fn into_inner(self) -> $inner {
361                self.0
362            }
363
364            /// Returns `true` if an underlying primitive integer is zero.
365            #[inline]
366            pub const fn is_zero(&self) -> bool {
367                self.0 == 0
368            }
369
370            /// Returns `true` if an underlying primitive integer fits into the repr.
371            #[inline]
372            pub const fn is_valid(&self) -> bool {
373                self.0 <= Self::MAX.0
374            }
375
376            /// Returns number of data bits that this struct occupies.
377            /// Returns `None` if an underlying primitive integer is too large.
378            pub const fn bit_len(&self) -> Option<u16> {
379                let bytes = (std::mem::size_of::<Self>() as u32 - self.0.leading_zeros() / 8) as u8;
380                if unlikely(bytes > $max_bytes) {
381                    None
382                } else {
383                    Some(Self::LEN_BITS + bytes as u16 * 8)
384                }
385            }
386
387            /// Returns number of data bits that this struct occupies.
388            /// Returns [`MAX_BITS`] if an underlying primitive integer is too large.
389            ///
390            /// [`MAX_BITS`]: Self::MAX_BITS
391            pub const fn unwrap_bit_len(&self) -> u16 {
392                let bytes = (std::mem::size_of::<Self>() as u32 - self.0.leading_zeros() / 8) as u8;
393                if unlikely(bytes > $max_bytes) {
394                    Self::MAX_BITS
395                } else {
396                    Self::LEN_BITS + bytes as u16 * 8
397                }
398            }
399
400            /// Saturating integer addition. Computes `self + rhs`,
401            /// saturating at the numeric bounds instead of overflowing.
402            #[inline]
403            #[must_use]
404            pub const fn saturating_add(self, rhs: Self) -> Self {
405                match self.0.checked_add(rhs.0) {
406                    Some(value) if value <= Self::MAX.0 => $ident(value),
407                    _ => Self::MAX,
408                }
409            }
410
411            /// Saturating integer addition. Computes `self - rhs`,
412            /// saturating at the numeric bounds instead of overflowing.
413            #[inline]
414            #[must_use]
415            pub const fn saturating_sub(self, rhs: Self) -> Self {
416                match self.0.checked_sub(rhs.0) {
417                    Some(value) if value <= Self::MAX.0 => $ident(value),
418                    Some(_) => Self::MAX,
419                    None => Self::ZERO,
420                }
421            }
422
423            /// Saturating integer multiplication. Computes `self * rhs`,
424            /// returning `None` if overflow occurred.
425            #[inline]
426            #[must_use]
427            pub const fn saturating_mul(self, rhs: Self) -> Self {
428                match self.0.checked_mul(rhs.0) {
429                    Some(value) if value <= Self::MAX.0 => $ident(value),
430                    _ => Self::MAX,
431                }
432            }
433
434            /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
435            #[inline]
436            #[must_use]
437            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
438                match self.0.checked_add(rhs.0) {
439                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
440                    _ => None,
441                }
442            }
443
444            /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
445            #[inline]
446            #[must_use]
447            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
448                match self.0.checked_sub(rhs.0) {
449                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
450                    _ => None,
451                }
452            }
453
454            /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
455            #[inline]
456            #[must_use]
457            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
458                match self.0.checked_mul(rhs.0) {
459                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
460                    _ => None,
461                }
462            }
463
464            /// Checked integer division. Computes `self / rhs`, returning None if `rhs == 0`
465            /// or overflow occurred.
466            #[inline]
467            #[must_use]
468            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
469                match self.0.checked_div(rhs.0) {
470                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
471                    _ => None,
472                }
473            }
474
475            /// Tries to add an other value to the current one.
476            pub fn try_add_assign(&mut self, other: Self) -> Result<(), Error> {
477                match self.checked_add(other) {
478                    Some(new_value) => {
479                        *self = new_value;
480                        Ok(())
481                    },
482                    None => Err(Error::IntOverflow),
483                }
484            }
485
486            /// Tries to subtract an other value from the current one.
487            pub fn try_sub_assign(&mut self, other: Self) -> Result<(), Error> {
488                match self.checked_sub(other) {
489                    Some(new_value) => {
490                        *self = new_value;
491                        Ok(())
492                    },
493                    None => Err(Error::IntOverflow),
494                }
495            }
496
497            /// Tries to multiply the current value by the other value.
498            pub fn try_mul_assign(&mut self, other: Self) -> Result<(), Error> {
499                match self.checked_mul(other) {
500                    Some(new_value) => {
501                        *self = new_value;
502                        Ok(())
503                    },
504                    None => Err(Error::IntOverflow),
505                }
506            }
507
508            /// Tries to divice the current value by the other value.
509            pub fn try_div_assign(&mut self, other: Self) -> Result<(), Error> {
510                match self.checked_div(other) {
511                    Some(new_value) => {
512                        *self = new_value;
513                        Ok(())
514                    },
515                    None => Err(Error::IntOverflow),
516                }
517            }
518        }
519
520        impl ExactSize for $ident {
521            #[inline]
522            fn exact_size(&self) -> Size {
523                Size {
524                    bits: self.bit_len().unwrap_or_default(),
525                    refs: 0,
526                }
527            }
528        }
529
530        impl_ops! { $ident, $inner }
531    };
532}
533
534impl_var_uints! {
535    /// Variable-length 24-bit integer.
536    ///
537    /// Stored as 2 bits of `len` (`0..=3`), followed by `len` bytes.
538    pub struct VarUint24(u32[..3]);
539
540    /// Variable-length 56-bit integer.
541    ///
542    /// Stored as 3 bits of `len` (`0..=7`), followed by `len` bytes.
543    pub struct VarUint56(u64[..7]);
544
545    /// Variable-length 120-bit integer. Used for native currencies.
546    ///
547    /// Stored as 4 bits of `len` (`0..=15`), followed by `len` bytes.
548    pub struct Tokens(u128[..15]);
549}
550
551impl_serde!(VarUint24, u32);
552impl_serde!(VarUint56, u64);
553
554#[cfg(feature = "serde")]
555impl serde::Serialize for Tokens {
556    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
557    where
558        S: serde::Serializer,
559    {
560        if serializer.is_human_readable() {
561            serializer.collect_str(&self.0)
562        } else {
563            self.0.serialize(serializer)
564        }
565    }
566}
567
568#[cfg(feature = "serde")]
569impl<'de> serde::Deserialize<'de> for Tokens {
570    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
571    where
572        D: serde::Deserializer<'de>,
573    {
574        use serde::de::{Error, Unexpected, Visitor};
575
576        struct Expected;
577
578        impl serde::de::Expected for Expected {
579            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
580                f.write_str(stringify!($ident))
581            }
582        }
583
584        struct TokensVisitor;
585
586        impl Visitor<'_> for TokensVisitor {
587            type Value = u128;
588
589            fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
590                f.write_str("a string with a number")
591            }
592
593            fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
594                v.parse().map_err(E::custom)
595            }
596        }
597
598        let res = Self::new(ok!(if deserializer.is_human_readable() {
599            deserializer.deserialize_str(TokensVisitor)
600        } else {
601            u128::deserialize(deserializer)
602        }));
603
604        if res.is_valid() {
605            Ok(res)
606        } else {
607            Err(D::Error::invalid_type(
608                Unexpected::Other("big number"),
609                &Expected,
610            ))
611        }
612    }
613}
614
615impl Store for VarUint24 {
616    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
617        let bytes = (4 - self.0.leading_zeros() / 8) as u8;
618        let bits = bytes as u16 * 8;
619
620        if unlikely(bytes > 3 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
621            return Err(Error::CellOverflow);
622        }
623
624        ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
625        builder.store_uint(self.0 as u64, bits)
626    }
627}
628
629impl<'a> Load<'a> for VarUint24 {
630    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
631        let bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
632        match slice.load_uint(bytes as u16 * 8) {
633            Ok(value) => Ok(Self(value as u32)),
634            Err(e) => Err(e),
635        }
636    }
637}
638
639impl Store for VarUint56 {
640    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
641        let bytes = (8 - self.0.leading_zeros() / 8) as u8;
642        let bits = bytes as u16 * 8;
643
644        if unlikely(bytes > 7 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
645            return Err(Error::CellOverflow);
646        }
647
648        ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
649        builder.store_uint(self.0, bits)
650    }
651}
652
653impl<'a> Load<'a> for VarUint56 {
654    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
655        let bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
656        match slice.load_uint(bytes as u16 * 8) {
657            Ok(value) => Ok(Self(value)),
658            Err(e) => Err(e),
659        }
660    }
661}
662
663impl Store for Tokens {
664    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
665        let bytes = (16 - self.0.leading_zeros() / 8) as u8;
666        let bits = bytes as u16 * 8;
667
668        if unlikely(bytes > 15 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
669            return Err(Error::CellOverflow);
670        }
671
672        ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
673        store_u128(builder, self.0, bits)
674    }
675}
676
677impl<'a> Load<'a> for Tokens {
678    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
679        let bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
680        match load_u128(slice, bytes) {
681            Ok(value) => Ok(Self(value)),
682            Err(e) => Err(e),
683        }
684    }
685}
686
687macro_rules! impl_small_uints {
688    ($($(#[doc = $doc:expr])* $vis:vis struct $ident:ident($bits:literal);)*) => {
689        $(
690            impl_small_uints!{@impl $(#[doc = $doc])* $vis $ident, $bits}
691        )*
692    };
693
694    (@impl $(#[doc = $doc:expr])* $vis:vis $ident:ident, $bits:literal) => {
695        $(#[doc = $doc])*
696        #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
697        #[repr(transparent)]
698        $vis struct $ident(u16);
699
700        impl $ident {
701            /// The additive identity for this integer type, i.e. `0`.
702            pub const ZERO: Self = $ident(0);
703
704            /// The multiplicative identity for this integer type, i.e. `1`.
705            pub const ONE: Self = $ident(1);
706
707            /// The smallest value that can be represented by this integer type.
708            pub const MIN: Self = $ident(0);
709
710            /// The largest value that can be represented by this integer type.
711            pub const MAX: Self = $ident((1u16 << $bits) - 1);
712
713            /// The number of data bits that this struct occupies.
714            pub const BITS: u16 = $bits;
715
716            /// Creates a new integer value from a primitive integer.
717            #[inline]
718            pub const fn new(value: u16) -> Self {
719                Self(value)
720            }
721
722            /// Converts integer into an underlying primitive integer.
723            #[inline]
724            pub const fn into_inner(self) -> u16 {
725                self.0
726            }
727
728            /// Returns `true` if an underlying primitive integer is zero.
729            #[inline]
730            pub const fn is_zero(&self) -> bool {
731                self.0 == 0
732            }
733
734            /// Returns `true` if an underlying primitive integer fits into the repr.
735            #[inline]
736            pub const fn is_valid(&self) -> bool {
737                self.0 <= Self::MAX.0
738            }
739
740            /// Saturating integer addition. Computes `self + rhs`,
741            /// saturating at the numeric bounds instead of overflowing.
742            #[inline]
743            #[must_use]
744            pub const fn saturating_add(self, rhs: Self) -> Self {
745                match self.0.checked_add(rhs.0) {
746                    Some(value) if value <= Self::MAX.0 => $ident(value),
747                    _ => Self::MAX,
748                }
749            }
750
751            /// Saturating integer addition. Computes `self - rhs`,
752            /// saturating at the numeric bounds instead of overflowing.
753            #[inline]
754            #[must_use]
755            pub const fn saturating_sub(self, rhs: Self) -> Self {
756                match self.0.checked_sub(rhs.0) {
757                    Some(value) if value <= Self::MAX.0 => $ident(value),
758                    Some(_) => Self::MAX,
759                    None => Self::MIN,
760                }
761            }
762
763            /// Saturating integer multiplication. Computes `self * rhs`,
764            /// returning `None` if overflow occurred.
765            #[inline]
766            #[must_use]
767            pub const fn saturating_mul(self, rhs: Self) -> Self {
768                match self.0.checked_mul(rhs.0) {
769                    Some(value) if value <= Self::MAX.0 => $ident(value),
770                    _ => Self::MAX,
771                }
772            }
773
774            /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
775            #[inline]
776            #[must_use]
777            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
778                match self.0.checked_add(rhs.0) {
779                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
780                    _ => None,
781                }
782            }
783
784            /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
785            #[inline]
786            #[must_use]
787            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
788                match self.0.checked_sub(rhs.0) {
789                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
790                    _ => None,
791                }
792            }
793
794            /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
795            #[inline]
796            #[must_use]
797            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
798                match self.0.checked_mul(rhs.0) {
799                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
800                    _ => None,
801                }
802            }
803
804            /// Checked integer division. Computes `self / rhs`, returning None if `rhs == 0`
805            /// or overflow occurred.
806            #[inline]
807            #[must_use]
808            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
809                match self.0.checked_div(rhs.0) {
810                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
811                    _ => None,
812                }
813            }
814        }
815
816        impl ExactSize for $ident {
817            #[inline]
818            fn exact_size(&self) -> Size {
819                Size { bits: $bits, refs: 0 }
820            }
821        }
822
823        impl Store for $ident {
824            fn store_into(
825                &self,
826                builder: &mut CellBuilder,
827                _: &dyn CellContext
828            ) -> Result<(), Error> {
829                if !self.is_valid() {
830                    return Err(Error::IntOverflow);
831                }
832                builder.store_uint(self.0 as u64, Self::BITS)
833            }
834        }
835
836        impl<'a> Load<'a> for $ident {
837            fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
838                match slice.load_uint(Self::BITS) {
839                    Ok(value) => Ok(Self(value as u16)),
840                    Err(e) => Err(e),
841                }
842            }
843        }
844
845        impl crate::dict::DictKey for $ident {
846            const BITS: u16 = $bits;
847        }
848
849        impl crate::dict::StoreDictKey for $ident {
850            #[inline]
851            fn store_into_data(&self, builder: &mut CellDataBuilder) -> Result<(), Error> {
852                if !self.is_valid() {
853                    return Err(Error::IntOverflow);
854                }
855                builder.store_uint(self.0 as u64, Self::BITS)
856            }
857        }
858
859        impl crate::dict::LoadDictKey for $ident {
860            #[inline]
861            fn load_from_data(data: &CellDataBuilder) -> Option<Self> {
862                let d = data.raw_data();
863                Some($ident(u16::from_be_bytes([d[0], d[1]]) >> (16 - $bits)))
864            }
865        }
866
867        impl_ops! { $ident, u16 }
868    };
869}
870
871impl_small_uints! {
872    /// Fixed-length 9-bit integer.
873    pub struct Uint9(9);
874
875    /// Fixed-length 12-bit integer.
876    pub struct Uint12(12);
877
878    /// Fixed-length 15-bit integer.
879    pub struct Uint15(15);
880}
881
882impl_serde!(Uint9, u16);
883impl_serde!(Uint12, u16);
884impl_serde!(Uint15, u16);
885
886#[cfg(feature = "arbitrary")]
887macro_rules! impl_arbitrary {
888    ($($ty:ty => $n:literal),*$(,)?) => {
889        $(impl<'a> arbitrary::Arbitrary<'a> for $ty {
890            #[inline]
891            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
892                u.int_in_range(0..=<$ty>::MAX.into_inner()).map(<$ty>::new)
893            }
894
895            #[inline]
896            fn size_hint(_: usize) -> (usize, Option<usize>) {
897                ($n, Some($n))
898            }
899        })*
900    };
901}
902
903#[cfg(feature = "arbitrary")]
904impl_arbitrary! {
905    Uint9 => 2,
906    Uint12 => 2,
907    Uint15 => 2,
908    VarUint24 => 4,
909    VarUint56 => 8,
910    Tokens => 16,
911}
912
913/// Account split depth. Fixed-length 5-bit integer of range `1..=30`
914#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
915#[repr(transparent)]
916pub struct SplitDepth(NonZeroU8);
917
918impl SplitDepth {
919    /// The minimum allowed number of bits in the rewrite prefix.
920    pub const MIN: Self = match NonZeroU8::new(1) {
921        Some(value) => Self(value),
922        None => unreachable!(),
923    };
924
925    /// The maximum allowed number of bits in the rewrite prefix.
926    pub const MAX: Self = match NonZeroU8::new(30) {
927        Some(value) => Self(value),
928        None => unreachable!(),
929    };
930
931    /// The number of data bits that this struct occupies.
932    pub const BITS: u16 = 5;
933
934    /// Creates a new integer value from a primitive integer.
935    #[inline]
936    pub const fn new(value: u8) -> Result<Self, Error> {
937        match NonZeroU8::new(value) {
938            Some(value) => Ok(Self(value)),
939            None => Err(Error::IntOverflow),
940        }
941    }
942
943    /// Creates a new integer value from bit len.
944    #[inline]
945    pub const fn from_bit_len(bit_len: u16) -> Result<Self, Error> {
946        if bit_len < u8::MAX as u16 {
947            Self::new(bit_len as u8)
948        } else {
949            Err(Error::IntOverflow)
950        }
951    }
952
953    /// Converts split depths into the number of bits.
954    #[inline]
955    pub const fn into_bit_len(self) -> u16 {
956        self.0.get() as u16
957    }
958}
959
960#[cfg(feature = "bigint")]
961impl From<SplitDepth> for num_bigint::BigInt {
962    #[inline]
963    fn from(value: SplitDepth) -> Self {
964        Self::from(value.0.get())
965    }
966}
967
968#[cfg(feature = "bigint")]
969impl From<SplitDepth> for num_bigint::BigUint {
970    #[inline]
971    fn from(value: SplitDepth) -> Self {
972        Self::from(value.0.get())
973    }
974}
975
976impl ExactSize for SplitDepth {
977    #[inline]
978    fn exact_size(&self) -> Size {
979        Size {
980            bits: Self::BITS,
981            refs: 0,
982        }
983    }
984}
985
986impl Store for SplitDepth {
987    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
988        builder.store_small_uint(self.0.get(), Self::BITS)
989    }
990}
991
992impl<'a> Load<'a> for SplitDepth {
993    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
994        match slice.load_small_uint(Self::BITS) {
995            Ok(value) => Self::new(value),
996            Err(e) => Err(e),
997        }
998    }
999}
1000
1001#[cfg(feature = "serde")]
1002impl serde::Serialize for SplitDepth {
1003    #[inline]
1004    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1005    where
1006        S: serde::Serializer,
1007    {
1008        self.0.get().serialize(serializer)
1009    }
1010}
1011
1012#[cfg(feature = "serde")]
1013impl<'de> serde::Deserialize<'de> for SplitDepth {
1014    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1015    where
1016        D: serde::Deserializer<'de>,
1017    {
1018        match u8::deserialize(deserializer) {
1019            Ok(value) => Self::new(value).map_err(serde::de::Error::custom),
1020            Err(e) => Err(e),
1021        }
1022    }
1023}
1024
1025#[cfg(feature = "arbitrary")]
1026impl<'a> arbitrary::Arbitrary<'a> for SplitDepth {
1027    #[inline]
1028    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
1029        const MIN: u8 = SplitDepth::MIN.into_bit_len() as u8;
1030        const MAX: u8 = SplitDepth::MAX.into_bit_len() as u8;
1031        Ok(Self::new(u.int_in_range(MIN..=MAX)?).unwrap())
1032    }
1033
1034    fn size_hint(_: usize) -> (usize, Option<usize>) {
1035        (1, Some(1))
1036    }
1037}
1038
1039fn store_u128(builder: &mut CellBuilder, value: u128, mut bits: u16) -> Result<(), Error> {
1040    if let Some(high_bits) = bits.checked_sub(64) {
1041        ok!(builder.store_uint((value >> 64) as u64, high_bits));
1042        bits -= high_bits;
1043    }
1044    builder.store_uint(value as u64, bits)
1045}
1046
1047fn load_u128(slice: &mut CellSlice<'_>, mut bytes: u8) -> Result<u128, Error> {
1048    let mut result: u128 = 0;
1049    if let Some(high_bytes) = bytes.checked_sub(8) {
1050        if high_bytes > 0 {
1051            result = (ok!(slice.load_uint(high_bytes as u16 * 8)) as u128) << 64;
1052            bytes -= high_bytes;
1053        }
1054    }
1055
1056    match slice.load_uint(bytes as u16 * 8) {
1057        Ok(value) => Ok(result | value as u128),
1058        Err(e) => Err(e),
1059    }
1060}
1061
1062#[cfg(test)]
1063mod tests {
1064    use super::*;
1065    use crate::prelude::CellBuilder;
1066
1067    macro_rules! impl_operation_tests {
1068        ($ident:ident$(, $check_max_div:ident)?) => {
1069            assert_eq!($ident::new(10) + $ident::new(4), $ident::new(14));
1070            assert_eq!($ident::new(10) + 4, $ident::new(14));
1071
1072            assert_eq!($ident::new(10) - $ident::new(4), $ident::new(6));
1073            assert_eq!($ident::new(10) - 4, $ident::new(6));
1074
1075            assert_eq!($ident::new(10) * $ident::new(4), $ident::new(40));
1076            assert_eq!($ident::new(10) * 4, $ident::new(40));
1077
1078            assert_eq!($ident::new(10) / $ident::new(2), $ident::new(5));
1079            assert_eq!($ident::new(10) / 2, $ident::new(5));
1080
1081            assert_eq!($ident::new(10) >> 2, $ident::new(2));
1082            assert_eq!($ident::new(10) << 2, $ident::new(40));
1083
1084            let mut value = $ident::new(10);
1085            value += 4;
1086            assert_eq!(value, $ident::new(14));
1087
1088            let mut value = $ident::new(10);
1089            value -= 4;
1090            assert_eq!(value, $ident::new(6));
1091
1092            let mut value = $ident::new(10);
1093            value *= 4;
1094            assert_eq!(value, $ident::new(40));
1095
1096            let mut value = $ident::new(10);
1097            value /= 2;
1098            assert_eq!(value, $ident::new(5));
1099
1100            let mut value = $ident::new(10);
1101            value >>= 2;
1102            assert_eq!(value, $ident::new(2));
1103
1104            let mut value = $ident::new(10);
1105            value <<= 2;
1106            assert_eq!(value, $ident::new(40));
1107
1108            assert!(!($ident::MAX + 1).is_valid());
1109
1110            assert_eq!($ident::MAX.checked_add($ident::new(1)), None);
1111            assert_eq!(
1112                ($ident::MAX - 1).checked_add($ident::new(1)),
1113                Some($ident::MAX)
1114            );
1115
1116            assert_eq!(($ident::MAX + 10).checked_sub($ident::new(1)), None);
1117            assert_eq!(
1118                ($ident::MAX + 10).checked_sub($ident::MAX),
1119                Some($ident::new(10)),
1120            );
1121            assert_eq!($ident::new(10).checked_sub($ident::MAX), None);
1122
1123            assert_eq!($ident::MAX.checked_mul($ident::new(2)), None);
1124            assert_eq!(
1125                ($ident::MAX / 2).checked_mul($ident::new(2)),
1126                Some($ident::MAX - 1)
1127            );
1128
1129            $(
1130                let $check_max_div = ();
1131                _ = $check_max_div;
1132                assert_eq!((($ident::MAX + 1) * 2).checked_div($ident::new(2)), None);
1133                assert_eq!(
1134                    ($ident::MAX * 2).checked_div($ident::new(2)),
1135                    Some($ident::MAX)
1136                );
1137                assert_eq!($ident::ONE.checked_div($ident::ZERO), None);
1138            )?
1139        };
1140    }
1141
1142    macro_rules! impl_serialization_tests {
1143        ($ident:ident, $max_bits:literal) => {
1144            let context = Cell::empty_context();
1145
1146            for i in 0..$max_bits {
1147                let value = $ident::ONE << i;
1148                let mut builder = CellBuilder::new();
1149
1150                if value <= $ident::MAX {
1151                    value.store_into(&mut builder, context).unwrap();
1152                    let cell = builder.build().unwrap();
1153                    assert_eq!(value.bit_len().unwrap(), cell.bit_len());
1154                } else {
1155                    assert!(value.store_into(&mut builder, context).is_err());
1156                }
1157            }
1158        };
1159    }
1160
1161    macro_rules! impl_deserialization_tests {
1162        ($ident:ident, $max_bits:literal, $value:literal) => {
1163            let context = Cell::empty_context();
1164
1165            let mut value = $ident::new($value);
1166            for _ in 0..=$max_bits {
1167                let mut builder = CellBuilder::new();
1168                value.store_into(&mut builder, context).unwrap();
1169                let cell = builder.build().unwrap();
1170
1171                let parsed_value = cell.parse::<$ident>().unwrap();
1172                assert_eq!(parsed_value, value);
1173
1174                value >>= 1;
1175            }
1176        };
1177    }
1178
1179    macro_rules! impl_fixed_len_serialization_tests {
1180        ($ident:ident, $max_bits:literal) => {
1181            let context = Cell::empty_context();
1182
1183            for i in 0..$max_bits {
1184                let value = $ident::ONE << i;
1185                let mut builder = CellBuilder::new();
1186
1187                if value <= $ident::MAX {
1188                    value.store_into(&mut builder, context).unwrap();
1189                    let cell = builder.build().unwrap();
1190                    assert_eq!($ident::BITS, cell.bit_len());
1191                } else {
1192                    assert!(value.store_into(&mut builder, context).is_err());
1193                }
1194            }
1195        };
1196    }
1197
1198    #[test]
1199    fn fixed_len_operations() {
1200        impl_operation_tests!(Uint9, check_max_div);
1201        impl_operation_tests!(Uint12, check_max_div);
1202        impl_operation_tests!(Uint15);
1203    }
1204
1205    #[test]
1206    fn fixed_len_serialization() {
1207        impl_fixed_len_serialization_tests!(Uint9, 16);
1208        impl_fixed_len_serialization_tests!(Uint12, 16);
1209        impl_fixed_len_serialization_tests!(Uint15, 16);
1210    }
1211
1212    #[test]
1213    fn fixed_len_deserialization() {
1214        impl_deserialization_tests!(Uint9, 9, 0b100110011);
1215        impl_deserialization_tests!(Uint12, 12, 0b111100110011);
1216        impl_deserialization_tests!(Uint15, 15, 0b11111100110011);
1217    }
1218
1219    #[test]
1220    fn var_uint24_operations() {
1221        impl_operation_tests!(VarUint24, check_max_div);
1222    }
1223
1224    #[test]
1225    fn var_uint56_operations() {
1226        impl_operation_tests!(VarUint56, check_max_div);
1227    }
1228
1229    #[test]
1230    fn tokens_operations() {
1231        impl_operation_tests!(Tokens, check_max_div);
1232    }
1233
1234    #[test]
1235    fn var_uint24_serialization() {
1236        impl_serialization_tests!(VarUint24, 32);
1237    }
1238
1239    #[test]
1240    fn var_uint56_serialization() {
1241        impl_serialization_tests!(VarUint56, 64);
1242    }
1243
1244    #[test]
1245    fn tokens_serialization() {
1246        impl_serialization_tests!(Tokens, 128);
1247    }
1248
1249    #[test]
1250    fn var_uint24_deserialization() {
1251        impl_deserialization_tests!(VarUint24, 24, 0xabcdef);
1252    }
1253
1254    #[test]
1255    fn var_uint56_deserialization() {
1256        impl_deserialization_tests!(VarUint56, 56, 0xabcdef89abcdef);
1257    }
1258
1259    #[test]
1260    fn tokens_deserialization() {
1261        impl_deserialization_tests!(Tokens, 120, 0xabcdef89abcdefdeadbeeffafacafe);
1262    }
1263
1264    fn _num_must_use() {
1265        #[expect(unused_must_use)]
1266        {
1267            Uint9::new(10).checked_add(Uint9::ZERO);
1268        }
1269
1270        #[expect(unused_must_use)]
1271        {
1272            Uint12::new(10).checked_add(Uint12::ZERO);
1273        }
1274
1275        #[expect(unused_must_use)]
1276        {
1277            Uint15::new(10).checked_add(Uint15::ZERO);
1278        }
1279
1280        #[expect(unused_must_use)]
1281        {
1282            VarUint24::new(10).checked_add(VarUint24::ZERO);
1283        }
1284
1285        #[expect(unused_must_use)]
1286        {
1287            VarUint56::new(10).checked_add(VarUint56::ZERO);
1288        }
1289
1290        #[expect(unused_must_use)]
1291        {
1292            Tokens::new(10).checked_add(Tokens::ZERO);
1293        }
1294
1295        #[expect(unused_must_use)]
1296        {
1297            VarUint248::new(10).checked_add(&VarUint248::ZERO);
1298        }
1299    }
1300}