1use 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 pub const ZERO: Self = $ident(0);
336
337 pub const ONE: Self = $ident(1);
339
340 pub const MIN: Self = $ident(0);
342
343 pub const MAX: Self = $ident(((1 as $inner) << ($max_bytes * 8)) - 1);
345
346 pub const LEN_BITS: u16 = 8 - ($max_bytes as u8).leading_zeros() as u16;
348
349 pub const MAX_BITS: u16 = Self::LEN_BITS + $max_bytes * 8;
351
352 #[inline]
354 pub const fn new(value: $inner) -> Self {
355 Self(value)
356 }
357
358 #[inline]
360 pub const fn into_inner(self) -> $inner {
361 self.0
362 }
363
364 #[inline]
366 pub const fn is_zero(&self) -> bool {
367 self.0 == 0
368 }
369
370 #[inline]
372 pub const fn is_valid(&self) -> bool {
373 self.0 <= Self::MAX.0
374 }
375
376 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 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 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 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 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 pub struct VarUint24(u32[..3]);
539
540 pub struct VarUint56(u64[..7]);
544
545 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 pub const ZERO: Self = $ident(0);
703
704 pub const ONE: Self = $ident(1);
706
707 pub const MIN: Self = $ident(0);
709
710 pub const MAX: Self = $ident((1u16 << $bits) - 1);
712
713 pub const BITS: u16 = $bits;
715
716 #[inline]
718 pub const fn new(value: u16) -> Self {
719 Self(value)
720 }
721
722 #[inline]
724 pub const fn into_inner(self) -> u16 {
725 self.0
726 }
727
728 #[inline]
730 pub const fn is_zero(&self) -> bool {
731 self.0 == 0
732 }
733
734 #[inline]
736 pub const fn is_valid(&self) -> bool {
737 self.0 <= Self::MAX.0
738 }
739
740 #[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 #[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 #[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 #[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 #[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 #[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 #[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 pub struct Uint9(9);
874
875 pub struct Uint12(12);
877
878 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#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
915#[repr(transparent)]
916pub struct SplitDepth(NonZeroU8);
917
918impl SplitDepth {
919 pub const MIN: Self = match NonZeroU8::new(1) {
921 Some(value) => Self(value),
922 None => unreachable!(),
923 };
924
925 pub const MAX: Self = match NonZeroU8::new(30) {
927 Some(value) => Self(value),
928 None => unreachable!(),
929 };
930
931 pub const BITS: u16 = 5;
933
934 #[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 #[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 #[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}