Skip to main content

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) << Self::VALUE_BITS) - 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 + Self::VALUE_BITS;
351
352            /// The maximum number of bits for the value.
353            pub const VALUE_BITS: u16 = $max_bytes * 8;
354
355            /// Creates a new integer value from a primitive integer.
356            #[inline]
357            pub const fn new(value: $inner) -> Self {
358                Self(value)
359            }
360
361            /// Converts integer into an underlying primitive integer.
362            #[inline]
363            pub const fn into_inner(self) -> $inner {
364                self.0
365            }
366
367            /// Returns `true` if an underlying primitive integer is zero.
368            #[inline]
369            pub const fn is_zero(&self) -> bool {
370                self.0 == 0
371            }
372
373            /// Returns `true` if an underlying primitive integer fits into the repr.
374            #[inline]
375            pub const fn is_valid(&self) -> bool {
376                self.0 <= Self::MAX.0
377            }
378
379            /// Returns number of data bits that this struct occupies.
380            /// Returns `None` if an underlying primitive integer is too large.
381            pub const fn bit_len(&self) -> Option<u16> {
382                let bytes = (std::mem::size_of::<Self>() as u32 - self.0.leading_zeros() / 8) as u8;
383                if unlikely(bytes > $max_bytes) {
384                    None
385                } else {
386                    Some(Self::LEN_BITS + bytes as u16 * 8)
387                }
388            }
389
390            /// Returns number of data bits that this struct occupies.
391            /// Returns [`MAX_BITS`] if an underlying primitive integer is too large.
392            ///
393            /// [`MAX_BITS`]: Self::MAX_BITS
394            pub const fn unwrap_bit_len(&self) -> u16 {
395                let bytes = (std::mem::size_of::<Self>() as u32 - self.0.leading_zeros() / 8) as u8;
396                if unlikely(bytes > $max_bytes) {
397                    Self::MAX_BITS
398                } else {
399                    Self::LEN_BITS + bytes as u16 * 8
400                }
401            }
402
403            /// Saturating integer addition. Computes `self + rhs`,
404            /// saturating at the numeric bounds instead of overflowing.
405            #[inline]
406            #[must_use]
407            pub const fn saturating_add(self, rhs: Self) -> Self {
408                match self.0.checked_add(rhs.0) {
409                    Some(value) if value <= Self::MAX.0 => $ident(value),
410                    _ => Self::MAX,
411                }
412            }
413
414            /// Saturating integer addition. Computes `self - rhs`,
415            /// saturating at the numeric bounds instead of overflowing.
416            #[inline]
417            #[must_use]
418            pub const fn saturating_sub(self, rhs: Self) -> Self {
419                match self.0.checked_sub(rhs.0) {
420                    Some(value) if value <= Self::MAX.0 => $ident(value),
421                    Some(_) => Self::MAX,
422                    None => Self::ZERO,
423                }
424            }
425
426            /// Saturating integer multiplication. Computes `self * rhs`,
427            /// returning `None` if overflow occurred.
428            #[inline]
429            #[must_use]
430            pub const fn saturating_mul(self, rhs: Self) -> Self {
431                match self.0.checked_mul(rhs.0) {
432                    Some(value) if value <= Self::MAX.0 => $ident(value),
433                    _ => Self::MAX,
434                }
435            }
436
437            /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
438            #[inline]
439            #[must_use]
440            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
441                match self.0.checked_add(rhs.0) {
442                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
443                    _ => None,
444                }
445            }
446
447            /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
448            #[inline]
449            #[must_use]
450            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
451                match self.0.checked_sub(rhs.0) {
452                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
453                    _ => None,
454                }
455            }
456
457            /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
458            #[inline]
459            #[must_use]
460            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
461                match self.0.checked_mul(rhs.0) {
462                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
463                    _ => None,
464                }
465            }
466
467            /// Checked integer division. Computes `self / rhs`, returning None if `rhs == 0`
468            /// or overflow occurred.
469            #[inline]
470            #[must_use]
471            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
472                match self.0.checked_div(rhs.0) {
473                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
474                    _ => None,
475                }
476            }
477
478            /// Tries to add an other value to the current one.
479            pub fn try_add_assign(&mut self, other: Self) -> Result<(), Error> {
480                match self.checked_add(other) {
481                    Some(new_value) => {
482                        *self = new_value;
483                        Ok(())
484                    },
485                    None => Err(Error::IntOverflow),
486                }
487            }
488
489            /// Tries to subtract an other value from the current one.
490            pub fn try_sub_assign(&mut self, other: Self) -> Result<(), Error> {
491                match self.checked_sub(other) {
492                    Some(new_value) => {
493                        *self = new_value;
494                        Ok(())
495                    },
496                    None => Err(Error::IntOverflow),
497                }
498            }
499
500            /// Tries to multiply the current value by the other value.
501            pub fn try_mul_assign(&mut self, other: Self) -> Result<(), Error> {
502                match self.checked_mul(other) {
503                    Some(new_value) => {
504                        *self = new_value;
505                        Ok(())
506                    },
507                    None => Err(Error::IntOverflow),
508                }
509            }
510
511            /// Tries to divice the current value by the other value.
512            pub fn try_div_assign(&mut self, other: Self) -> Result<(), Error> {
513                match self.checked_div(other) {
514                    Some(new_value) => {
515                        *self = new_value;
516                        Ok(())
517                    },
518                    None => Err(Error::IntOverflow),
519                }
520            }
521        }
522
523        impl ExactSize for $ident {
524            #[inline]
525            fn exact_size(&self) -> Size {
526                Size {
527                    bits: self.bit_len().unwrap_or_default(),
528                    refs: 0,
529                }
530            }
531        }
532
533        impl_ops! { $ident, $inner }
534    };
535}
536
537impl_var_uints! {
538    /// Variable-length 24-bit integer.
539    ///
540    /// Stored as 2 bits of `len` (`0..=3`), followed by `len` bytes.
541    pub struct VarUint24(u32[..3]);
542
543    /// Variable-length 56-bit integer.
544    ///
545    /// Stored as 3 bits of `len` (`0..=7`), followed by `len` bytes.
546    pub struct VarUint56(u64[..7]);
547
548    /// Variable-length 120-bit integer. Used for native currencies.
549    ///
550    /// Stored as 4 bits of `len` (`0..=15`), followed by `len` bytes.
551    pub struct Tokens(u128[..15]);
552}
553
554impl_serde!(VarUint24, u32);
555impl_serde!(VarUint56, u64);
556
557#[cfg(feature = "serde")]
558impl serde::Serialize for Tokens {
559    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
560    where
561        S: serde::Serializer,
562    {
563        if serializer.is_human_readable() {
564            serializer.collect_str(&self.0)
565        } else {
566            self.0.serialize(serializer)
567        }
568    }
569}
570
571#[cfg(feature = "serde")]
572impl<'de> serde::Deserialize<'de> for Tokens {
573    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
574    where
575        D: serde::Deserializer<'de>,
576    {
577        use serde::de::{Error, Unexpected, Visitor};
578
579        struct Expected;
580
581        impl serde::de::Expected for Expected {
582            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
583                f.write_str(stringify!($ident))
584            }
585        }
586
587        struct TokensVisitor;
588
589        impl Visitor<'_> for TokensVisitor {
590            type Value = u128;
591
592            fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
593                f.write_str("a string with a number")
594            }
595
596            fn visit_str<E: Error>(self, v: &str) -> Result<Self::Value, E> {
597                v.parse().map_err(E::custom)
598            }
599        }
600
601        let res = Self::new(ok!(if deserializer.is_human_readable() {
602            deserializer.deserialize_str(TokensVisitor)
603        } else {
604            u128::deserialize(deserializer)
605        }));
606
607        if res.is_valid() {
608            Ok(res)
609        } else {
610            Err(D::Error::invalid_type(
611                Unexpected::Other("big number"),
612                &Expected,
613            ))
614        }
615    }
616}
617
618impl Store for VarUint24 {
619    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
620        let bytes = (4 - self.0.leading_zeros() / 8) as u8;
621        let bits = bytes as u16 * 8;
622
623        if unlikely(bytes > 3 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
624            return Err(Error::CellOverflow);
625        }
626
627        ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
628        builder.store_uint(self.0 as u64, bits)
629    }
630}
631
632impl<'a> Load<'a> for VarUint24 {
633    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
634        let bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
635        match slice.load_uint(bytes as u16 * 8) {
636            Ok(value) => Ok(Self(value as u32)),
637            Err(e) => Err(e),
638        }
639    }
640}
641
642impl Store for VarUint56 {
643    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
644        let bytes = (8 - self.0.leading_zeros() / 8) as u8;
645        let bits = bytes as u16 * 8;
646
647        if unlikely(bytes > 7 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
648            return Err(Error::CellOverflow);
649        }
650
651        ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
652        builder.store_uint(self.0, bits)
653    }
654}
655
656impl<'a> Load<'a> for VarUint56 {
657    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
658        let bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
659        match slice.load_uint(bytes as u16 * 8) {
660            Ok(value) => Ok(Self(value)),
661            Err(e) => Err(e),
662        }
663    }
664}
665
666impl Store for Tokens {
667    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
668        let bytes = (16 - self.0.leading_zeros() / 8) as u8;
669        let bits = bytes as u16 * 8;
670
671        if unlikely(bytes > 15 || !builder.has_capacity(Self::LEN_BITS + bits, 0)) {
672            return Err(Error::CellOverflow);
673        }
674
675        ok!(builder.store_small_uint(bytes, Self::LEN_BITS));
676        store_u128(builder, self.0, bits)
677    }
678}
679
680impl<'a> Load<'a> for Tokens {
681    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
682        let bytes = ok!(slice.load_small_uint(Self::LEN_BITS));
683        match load_u128(slice, bytes) {
684            Ok(value) => Ok(Self(value)),
685            Err(e) => Err(e),
686        }
687    }
688}
689
690macro_rules! impl_small_uints {
691    ($($(#[doc = $doc:expr])* $vis:vis struct $ident:ident($bits:literal);)*) => {
692        $(
693            impl_small_uints!{@impl $(#[doc = $doc])* $vis $ident, $bits}
694        )*
695    };
696
697    (@impl $(#[doc = $doc:expr])* $vis:vis $ident:ident, $bits:literal) => {
698        $(#[doc = $doc])*
699        #[derive(Debug, Default, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
700        #[repr(transparent)]
701        $vis struct $ident(u16);
702
703        impl $ident {
704            /// The additive identity for this integer type, i.e. `0`.
705            pub const ZERO: Self = $ident(0);
706
707            /// The multiplicative identity for this integer type, i.e. `1`.
708            pub const ONE: Self = $ident(1);
709
710            /// The smallest value that can be represented by this integer type.
711            pub const MIN: Self = $ident(0);
712
713            /// The largest value that can be represented by this integer type.
714            pub const MAX: Self = $ident((1u16 << $bits) - 1);
715
716            /// The number of data bits that this struct occupies.
717            pub const BITS: u16 = $bits;
718
719            /// Creates a new integer value from a primitive integer.
720            #[inline]
721            pub const fn new(value: u16) -> Self {
722                Self(value)
723            }
724
725            /// Converts integer into an underlying primitive integer.
726            #[inline]
727            pub const fn into_inner(self) -> u16 {
728                self.0
729            }
730
731            /// Returns `true` if an underlying primitive integer is zero.
732            #[inline]
733            pub const fn is_zero(&self) -> bool {
734                self.0 == 0
735            }
736
737            /// Returns `true` if an underlying primitive integer fits into the repr.
738            #[inline]
739            pub const fn is_valid(&self) -> bool {
740                self.0 <= Self::MAX.0
741            }
742
743            /// Saturating integer addition. Computes `self + rhs`,
744            /// saturating at the numeric bounds instead of overflowing.
745            #[inline]
746            #[must_use]
747            pub const fn saturating_add(self, rhs: Self) -> Self {
748                match self.0.checked_add(rhs.0) {
749                    Some(value) if value <= Self::MAX.0 => $ident(value),
750                    _ => Self::MAX,
751                }
752            }
753
754            /// Saturating integer addition. Computes `self - rhs`,
755            /// saturating at the numeric bounds instead of overflowing.
756            #[inline]
757            #[must_use]
758            pub const fn saturating_sub(self, rhs: Self) -> Self {
759                match self.0.checked_sub(rhs.0) {
760                    Some(value) if value <= Self::MAX.0 => $ident(value),
761                    Some(_) => Self::MAX,
762                    None => Self::MIN,
763                }
764            }
765
766            /// Saturating integer multiplication. Computes `self * rhs`,
767            /// returning `None` if overflow occurred.
768            #[inline]
769            #[must_use]
770            pub const fn saturating_mul(self, rhs: Self) -> Self {
771                match self.0.checked_mul(rhs.0) {
772                    Some(value) if value <= Self::MAX.0 => $ident(value),
773                    _ => Self::MAX,
774                }
775            }
776
777            /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred.
778            #[inline]
779            #[must_use]
780            pub const fn checked_add(self, rhs: Self) -> Option<Self> {
781                match self.0.checked_add(rhs.0) {
782                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
783                    _ => None,
784                }
785            }
786
787            /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred.
788            #[inline]
789            #[must_use]
790            pub const fn checked_sub(self, rhs: Self) -> Option<Self> {
791                match self.0.checked_sub(rhs.0) {
792                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
793                    _ => None,
794                }
795            }
796
797            /// Checked integer multiplication. Computes `self * rhs`, returning `None` if overflow occurred.
798            #[inline]
799            #[must_use]
800            pub const fn checked_mul(self, rhs: Self) -> Option<Self> {
801                match self.0.checked_mul(rhs.0) {
802                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
803                    _ => None,
804                }
805            }
806
807            /// Checked integer division. Computes `self / rhs`, returning None if `rhs == 0`
808            /// or overflow occurred.
809            #[inline]
810            #[must_use]
811            pub const fn checked_div(self, rhs: Self) -> Option<Self> {
812                match self.0.checked_div(rhs.0) {
813                    Some(value) if value <= Self::MAX.0 => Some($ident(value)),
814                    _ => None,
815                }
816            }
817        }
818
819        impl ExactSize for $ident {
820            #[inline]
821            fn exact_size(&self) -> Size {
822                Size { bits: $bits, refs: 0 }
823            }
824        }
825
826        impl Store for $ident {
827            fn store_into(
828                &self,
829                builder: &mut CellBuilder,
830                _: &dyn CellContext
831            ) -> Result<(), Error> {
832                if !self.is_valid() {
833                    return Err(Error::IntOverflow);
834                }
835                builder.store_uint(self.0 as u64, Self::BITS)
836            }
837        }
838
839        impl<'a> Load<'a> for $ident {
840            fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
841                match slice.load_uint(Self::BITS) {
842                    Ok(value) => Ok(Self(value as u16)),
843                    Err(e) => Err(e),
844                }
845            }
846        }
847
848        impl crate::dict::DictKey for $ident {
849            const BITS: u16 = $bits;
850        }
851
852        impl crate::dict::StoreDictKey for $ident {
853            #[inline]
854            fn store_into_data(&self, builder: &mut CellDataBuilder) -> Result<(), Error> {
855                if !self.is_valid() {
856                    return Err(Error::IntOverflow);
857                }
858                builder.store_uint(self.0 as u64, Self::BITS)
859            }
860        }
861
862        impl crate::dict::LoadDictKey for $ident {
863            #[inline]
864            fn load_from_data(data: &CellDataBuilder) -> Option<Self> {
865                let d = data.raw_data();
866                Some($ident(u16::from_be_bytes([d[0], d[1]]) >> (16 - $bits)))
867            }
868        }
869
870        impl_ops! { $ident, u16 }
871    };
872}
873
874impl_small_uints! {
875    /// Fixed-length 9-bit integer.
876    pub struct Uint9(9);
877
878    /// Fixed-length 12-bit integer.
879    pub struct Uint12(12);
880
881    /// Fixed-length 15-bit integer.
882    pub struct Uint15(15);
883}
884
885impl_serde!(Uint9, u16);
886impl_serde!(Uint12, u16);
887impl_serde!(Uint15, u16);
888
889#[cfg(feature = "arbitrary")]
890macro_rules! impl_arbitrary {
891    ($($ty:ty => $n:literal),*$(,)?) => {
892        $(impl<'a> arbitrary::Arbitrary<'a> for $ty {
893            #[inline]
894            fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
895                u.int_in_range(0..=<$ty>::MAX.into_inner()).map(<$ty>::new)
896            }
897
898            #[inline]
899            fn size_hint(_: usize) -> (usize, Option<usize>) {
900                ($n, Some($n))
901            }
902        })*
903    };
904}
905
906#[cfg(feature = "arbitrary")]
907impl_arbitrary! {
908    Uint9 => 2,
909    Uint12 => 2,
910    Uint15 => 2,
911    VarUint24 => 4,
912    VarUint56 => 8,
913    Tokens => 16,
914}
915
916/// Account split depth. Fixed-length 5-bit integer of range `1..=30`
917#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
918#[repr(transparent)]
919pub struct SplitDepth(NonZeroU8);
920
921impl SplitDepth {
922    /// The minimum allowed number of bits in the rewrite prefix.
923    pub const MIN: Self = match NonZeroU8::new(1) {
924        Some(value) => Self(value),
925        None => unreachable!(),
926    };
927
928    /// The maximum allowed number of bits in the rewrite prefix.
929    pub const MAX: Self = match NonZeroU8::new(30) {
930        Some(value) => Self(value),
931        None => unreachable!(),
932    };
933
934    /// The number of data bits that this struct occupies.
935    pub const BITS: u16 = 5;
936
937    /// Creates a new integer value from a primitive integer.
938    #[inline]
939    pub const fn new(value: u8) -> Result<Self, Error> {
940        match NonZeroU8::new(value) {
941            Some(value) => Ok(Self(value)),
942            None => Err(Error::IntOverflow),
943        }
944    }
945
946    /// Creates a new integer value from bit len.
947    #[inline]
948    pub const fn from_bit_len(bit_len: u16) -> Result<Self, Error> {
949        if bit_len < u8::MAX as u16 {
950            Self::new(bit_len as u8)
951        } else {
952            Err(Error::IntOverflow)
953        }
954    }
955
956    /// Converts split depths into the number of bits.
957    #[inline]
958    pub const fn into_bit_len(self) -> u16 {
959        self.0.get() as u16
960    }
961}
962
963#[cfg(feature = "bigint")]
964impl From<SplitDepth> for num_bigint::BigInt {
965    #[inline]
966    fn from(value: SplitDepth) -> Self {
967        Self::from(value.0.get())
968    }
969}
970
971#[cfg(feature = "bigint")]
972impl From<SplitDepth> for num_bigint::BigUint {
973    #[inline]
974    fn from(value: SplitDepth) -> Self {
975        Self::from(value.0.get())
976    }
977}
978
979impl ExactSize for SplitDepth {
980    #[inline]
981    fn exact_size(&self) -> Size {
982        Size {
983            bits: Self::BITS,
984            refs: 0,
985        }
986    }
987}
988
989impl Store for SplitDepth {
990    fn store_into(&self, builder: &mut CellBuilder, _: &dyn CellContext) -> Result<(), Error> {
991        builder.store_small_uint(self.0.get(), Self::BITS)
992    }
993}
994
995impl<'a> Load<'a> for SplitDepth {
996    fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
997        match slice.load_small_uint(Self::BITS) {
998            Ok(value) => Self::new(value),
999            Err(e) => Err(e),
1000        }
1001    }
1002}
1003
1004#[cfg(feature = "serde")]
1005impl serde::Serialize for SplitDepth {
1006    #[inline]
1007    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1008    where
1009        S: serde::Serializer,
1010    {
1011        self.0.get().serialize(serializer)
1012    }
1013}
1014
1015#[cfg(feature = "serde")]
1016impl<'de> serde::Deserialize<'de> for SplitDepth {
1017    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1018    where
1019        D: serde::Deserializer<'de>,
1020    {
1021        match u8::deserialize(deserializer) {
1022            Ok(value) => Self::new(value).map_err(serde::de::Error::custom),
1023            Err(e) => Err(e),
1024        }
1025    }
1026}
1027
1028#[cfg(feature = "arbitrary")]
1029impl<'a> arbitrary::Arbitrary<'a> for SplitDepth {
1030    #[inline]
1031    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
1032        const MIN: u8 = SplitDepth::MIN.into_bit_len() as u8;
1033        const MAX: u8 = SplitDepth::MAX.into_bit_len() as u8;
1034        Ok(Self::new(u.int_in_range(MIN..=MAX)?).unwrap())
1035    }
1036
1037    fn size_hint(_: usize) -> (usize, Option<usize>) {
1038        (1, Some(1))
1039    }
1040}
1041
1042fn store_u128(builder: &mut CellBuilder, value: u128, mut bits: u16) -> Result<(), Error> {
1043    if let Some(high_bits) = bits.checked_sub(64) {
1044        ok!(builder.store_uint((value >> 64) as u64, high_bits));
1045        bits -= high_bits;
1046    }
1047    builder.store_uint(value as u64, bits)
1048}
1049
1050fn load_u128(slice: &mut CellSlice<'_>, mut bytes: u8) -> Result<u128, Error> {
1051    let mut result: u128 = 0;
1052    if let Some(high_bytes) = bytes.checked_sub(8)
1053        && high_bytes > 0
1054    {
1055        result = (ok!(slice.load_uint(high_bytes as u16 * 8)) as u128) << 64;
1056        bytes -= high_bytes;
1057    }
1058
1059    match slice.load_uint(bytes as u16 * 8) {
1060        Ok(value) => Ok(result | value as u128),
1061        Err(e) => Err(e),
1062    }
1063}
1064
1065#[cfg(test)]
1066mod tests {
1067    use super::*;
1068    use crate::prelude::CellBuilder;
1069
1070    macro_rules! impl_operation_tests {
1071        ($ident:ident$(, $check_max_div:ident)?) => {
1072            assert_eq!($ident::new(10) + $ident::new(4), $ident::new(14));
1073            assert_eq!($ident::new(10) + 4, $ident::new(14));
1074
1075            assert_eq!($ident::new(10) - $ident::new(4), $ident::new(6));
1076            assert_eq!($ident::new(10) - 4, $ident::new(6));
1077
1078            assert_eq!($ident::new(10) * $ident::new(4), $ident::new(40));
1079            assert_eq!($ident::new(10) * 4, $ident::new(40));
1080
1081            assert_eq!($ident::new(10) / $ident::new(2), $ident::new(5));
1082            assert_eq!($ident::new(10) / 2, $ident::new(5));
1083
1084            assert_eq!($ident::new(10) >> 2, $ident::new(2));
1085            assert_eq!($ident::new(10) << 2, $ident::new(40));
1086
1087            let mut value = $ident::new(10);
1088            value += 4;
1089            assert_eq!(value, $ident::new(14));
1090
1091            let mut value = $ident::new(10);
1092            value -= 4;
1093            assert_eq!(value, $ident::new(6));
1094
1095            let mut value = $ident::new(10);
1096            value *= 4;
1097            assert_eq!(value, $ident::new(40));
1098
1099            let mut value = $ident::new(10);
1100            value /= 2;
1101            assert_eq!(value, $ident::new(5));
1102
1103            let mut value = $ident::new(10);
1104            value >>= 2;
1105            assert_eq!(value, $ident::new(2));
1106
1107            let mut value = $ident::new(10);
1108            value <<= 2;
1109            assert_eq!(value, $ident::new(40));
1110
1111            assert!(!($ident::MAX + 1).is_valid());
1112
1113            assert_eq!($ident::MAX.checked_add($ident::new(1)), None);
1114            assert_eq!(
1115                ($ident::MAX - 1).checked_add($ident::new(1)),
1116                Some($ident::MAX)
1117            );
1118
1119            assert_eq!(($ident::MAX + 10).checked_sub($ident::new(1)), None);
1120            assert_eq!(
1121                ($ident::MAX + 10).checked_sub($ident::MAX),
1122                Some($ident::new(10)),
1123            );
1124            assert_eq!($ident::new(10).checked_sub($ident::MAX), None);
1125
1126            assert_eq!($ident::MAX.checked_mul($ident::new(2)), None);
1127            assert_eq!(
1128                ($ident::MAX / 2).checked_mul($ident::new(2)),
1129                Some($ident::MAX - 1)
1130            );
1131
1132            $(
1133                let $check_max_div = ();
1134                _ = $check_max_div;
1135                assert_eq!((($ident::MAX + 1) * 2).checked_div($ident::new(2)), None);
1136                assert_eq!(
1137                    ($ident::MAX * 2).checked_div($ident::new(2)),
1138                    Some($ident::MAX)
1139                );
1140                assert_eq!($ident::ONE.checked_div($ident::ZERO), None);
1141            )?
1142        };
1143    }
1144
1145    macro_rules! impl_serialization_tests {
1146        ($ident:ident, $max_bits:literal) => {
1147            let context = Cell::empty_context();
1148
1149            for i in 0..$max_bits {
1150                let value = $ident::ONE << i;
1151                let mut builder = CellBuilder::new();
1152
1153                if value <= $ident::MAX {
1154                    value.store_into(&mut builder, context).unwrap();
1155                    let cell = builder.build().unwrap();
1156                    assert_eq!(value.bit_len().unwrap(), cell.bit_len());
1157                } else {
1158                    assert!(value.store_into(&mut builder, context).is_err());
1159                }
1160            }
1161        };
1162    }
1163
1164    macro_rules! impl_deserialization_tests {
1165        ($ident:ident, $max_bits:literal, $value:literal) => {
1166            let context = Cell::empty_context();
1167
1168            let mut value = $ident::new($value);
1169            for _ in 0..=$max_bits {
1170                let mut builder = CellBuilder::new();
1171                value.store_into(&mut builder, context).unwrap();
1172                let cell = builder.build().unwrap();
1173
1174                let parsed_value = cell.parse::<$ident>().unwrap();
1175                assert_eq!(parsed_value, value);
1176
1177                value >>= 1;
1178            }
1179        };
1180    }
1181
1182    macro_rules! impl_fixed_len_serialization_tests {
1183        ($ident:ident, $max_bits:literal) => {
1184            let context = Cell::empty_context();
1185
1186            for i in 0..$max_bits {
1187                let value = $ident::ONE << i;
1188                let mut builder = CellBuilder::new();
1189
1190                if value <= $ident::MAX {
1191                    value.store_into(&mut builder, context).unwrap();
1192                    let cell = builder.build().unwrap();
1193                    assert_eq!($ident::BITS, cell.bit_len());
1194                } else {
1195                    assert!(value.store_into(&mut builder, context).is_err());
1196                }
1197            }
1198        };
1199    }
1200
1201    #[test]
1202    fn fixed_len_operations() {
1203        impl_operation_tests!(Uint9, check_max_div);
1204        impl_operation_tests!(Uint12, check_max_div);
1205        impl_operation_tests!(Uint15);
1206    }
1207
1208    #[test]
1209    fn fixed_len_serialization() {
1210        impl_fixed_len_serialization_tests!(Uint9, 16);
1211        impl_fixed_len_serialization_tests!(Uint12, 16);
1212        impl_fixed_len_serialization_tests!(Uint15, 16);
1213    }
1214
1215    #[test]
1216    fn fixed_len_deserialization() {
1217        impl_deserialization_tests!(Uint9, 9, 0b100110011);
1218        impl_deserialization_tests!(Uint12, 12, 0b111100110011);
1219        impl_deserialization_tests!(Uint15, 15, 0b11111100110011);
1220    }
1221
1222    #[test]
1223    fn var_uint24_operations() {
1224        impl_operation_tests!(VarUint24, check_max_div);
1225    }
1226
1227    #[test]
1228    fn var_uint56_operations() {
1229        impl_operation_tests!(VarUint56, check_max_div);
1230    }
1231
1232    #[test]
1233    fn tokens_operations() {
1234        impl_operation_tests!(Tokens, check_max_div);
1235    }
1236
1237    #[test]
1238    fn var_uint24_serialization() {
1239        impl_serialization_tests!(VarUint24, 32);
1240    }
1241
1242    #[test]
1243    fn var_uint56_serialization() {
1244        impl_serialization_tests!(VarUint56, 64);
1245    }
1246
1247    #[test]
1248    fn tokens_serialization() {
1249        impl_serialization_tests!(Tokens, 128);
1250    }
1251
1252    #[test]
1253    fn var_uint24_deserialization() {
1254        impl_deserialization_tests!(VarUint24, 24, 0xabcdef);
1255    }
1256
1257    #[test]
1258    fn var_uint56_deserialization() {
1259        impl_deserialization_tests!(VarUint56, 56, 0xabcdef89abcdef);
1260    }
1261
1262    #[test]
1263    fn tokens_deserialization() {
1264        impl_deserialization_tests!(Tokens, 120, 0xabcdef89abcdefdeadbeeffafacafe);
1265    }
1266
1267    fn _num_must_use() {
1268        #[expect(unused_must_use)]
1269        {
1270            Uint9::new(10).checked_add(Uint9::ZERO);
1271        }
1272
1273        #[expect(unused_must_use)]
1274        {
1275            Uint12::new(10).checked_add(Uint12::ZERO);
1276        }
1277
1278        #[expect(unused_must_use)]
1279        {
1280            Uint15::new(10).checked_add(Uint15::ZERO);
1281        }
1282
1283        #[expect(unused_must_use)]
1284        {
1285            VarUint24::new(10).checked_add(VarUint24::ZERO);
1286        }
1287
1288        #[expect(unused_must_use)]
1289        {
1290            VarUint56::new(10).checked_add(VarUint56::ZERO);
1291        }
1292
1293        #[expect(unused_must_use)]
1294        {
1295            Tokens::new(10).checked_add(Tokens::ZERO);
1296        }
1297
1298        #[expect(unused_must_use)]
1299        {
1300            VarUint248::new(10).checked_add(&VarUint248::ZERO);
1301        }
1302    }
1303}