everscale_types/num/
mod.rs

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