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) << Self::VALUE_BITS) - 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 + Self::VALUE_BITS;
351
352 pub const VALUE_BITS: u16 = $max_bytes * 8;
354
355 #[inline]
357 pub const fn new(value: $inner) -> Self {
358 Self(value)
359 }
360
361 #[inline]
363 pub const fn into_inner(self) -> $inner {
364 self.0
365 }
366
367 #[inline]
369 pub const fn is_zero(&self) -> bool {
370 self.0 == 0
371 }
372
373 #[inline]
375 pub const fn is_valid(&self) -> bool {
376 self.0 <= Self::MAX.0
377 }
378
379 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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 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 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 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 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 pub struct VarUint24(u32[..3]);
542
543 pub struct VarUint56(u64[..7]);
547
548 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 pub const ZERO: Self = $ident(0);
706
707 pub const ONE: Self = $ident(1);
709
710 pub const MIN: Self = $ident(0);
712
713 pub const MAX: Self = $ident((1u16 << $bits) - 1);
715
716 pub const BITS: u16 = $bits;
718
719 #[inline]
721 pub const fn new(value: u16) -> Self {
722 Self(value)
723 }
724
725 #[inline]
727 pub const fn into_inner(self) -> u16 {
728 self.0
729 }
730
731 #[inline]
733 pub const fn is_zero(&self) -> bool {
734 self.0 == 0
735 }
736
737 #[inline]
739 pub const fn is_valid(&self) -> bool {
740 self.0 <= Self::MAX.0
741 }
742
743 #[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 #[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 #[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 #[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 #[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 #[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 #[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 pub struct Uint9(9);
877
878 pub struct Uint12(12);
880
881 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#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Ord, PartialOrd)]
918#[repr(transparent)]
919pub struct SplitDepth(NonZeroU8);
920
921impl SplitDepth {
922 pub const MIN: Self = match NonZeroU8::new(1) {
924 Some(value) => Self(value),
925 None => unreachable!(),
926 };
927
928 pub const MAX: Self = match NonZeroU8::new(30) {
930 Some(value) => Self(value),
931 None => unreachable!(),
932 };
933
934 pub const BITS: u16 = 5;
936
937 #[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 #[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 #[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}