1use cfg_if::cfg_if;
2use core::{
3 cmp::{self, Ordering},
4 fmt,
5 mem::MaybeUninit,
6 ops::{Bound, Deref, RangeBounds},
7 slice,
8};
9use ruint::aliases::U256;
10use smallvec::SmallVec;
11
12#[cfg(not(feature = "nightly"))]
13#[allow(unused_imports)]
14use core::convert::{identity as likely, identity as unlikely};
15#[cfg(feature = "nightly")]
16#[allow(unused_imports)]
17use core::intrinsics::{likely, unlikely};
18
19#[cfg(not(feature = "std"))]
20use alloc::vec::Vec;
21
22const NIBBLES: usize = 64;
24
25static SLICE_MASKS: [U256; 65] = {
34 let mut masks = [U256::ZERO; 65];
35 let mut i = 0;
36 while i <= NIBBLES {
37 masks[i] = if i == 0 { U256::ZERO } else { U256::MAX.wrapping_shl((NIBBLES - i) * 4) };
38 i += 1;
39 }
40 masks
41};
42
43static INCREMENT_VALUES: [U256; 65] = {
47 let mut masks = [U256::ZERO; 65];
48 let mut i = 0;
49 while i <= NIBBLES {
50 masks[i] = U256::ONE.wrapping_shl((NIBBLES - i) * 4);
51 i += 1;
52 }
53 masks
54};
55
56#[repr(C)] #[derive(Default, Clone, Copy, Hash, PartialEq, Eq)]
89pub struct Nibbles {
90 pub(crate) length: usize,
94 pub(crate) nibbles: U256,
97}
98
99impl fmt::Debug for Nibbles {
100 #[inline]
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 if self.is_empty() {
103 write!(f, "Nibbles(0x)")
104 } else {
105 let shifted = self.nibbles >> ((NIBBLES - self.len()) * 4);
106 write!(f, "Nibbles(0x{:0width$x})", shifted, width = self.len())
107 }
108 }
109}
110
111#[cfg(feature = "arbitrary")]
112impl<'a> arbitrary::Arbitrary<'a> for Nibbles {
113 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
114 let length = u.int_in_range(0..=NIBBLES)?;
115 let nibbles = Nibbles::from_nibbles_unchecked(
116 (0..length).map(|_| u.int_in_range(0..=0xf)).collect::<Result<Vec<_>, _>>()?,
117 );
118 Ok(nibbles)
119 }
120}
121
122impl Ord for Nibbles {
126 #[inline]
127 fn cmp(&self, other: &Self) -> Ordering {
128 let self_len = self.len().div_ceil(2);
129 let other_len = other.len().div_ceil(2);
130 let l = cmp::min(self_len, other_len);
131
132 let lhs = &as_le_slice(&self.nibbles)[U256::BYTES - l..];
135 let rhs = &as_le_slice(&other.nibbles)[U256::BYTES - l..];
136
137 for i in (0..l).rev() {
138 match lhs[i].cmp(&rhs[i]) {
139 Ordering::Equal => (),
140 non_eq => return non_eq,
141 }
142 }
143
144 self.len().cmp(&other.len())
145 }
146}
147
148impl PartialOrd for Nibbles {
149 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
150 Some(self.cmp(other))
151 }
152}
153
154impl FromIterator<u8> for Nibbles {
155 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
156 let mut nibbles = Self::default();
157 for n in iter {
158 nibbles.push(n);
159 }
160 nibbles
161 }
162}
163
164#[cfg(feature = "rlp")]
165impl alloy_rlp::Encodable for Nibbles {
166 #[inline]
167 fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
168 alloy_rlp::Header { list: true, payload_length: self.len() }.encode(out);
169 for i in 0..self.len() {
170 self.get_unchecked(i).encode(out);
171 }
172 }
173
174 #[inline]
175 fn length(&self) -> usize {
176 let payload_length = self.len();
177 payload_length + alloy_rlp::length_of_length(payload_length)
178 }
179}
180
181#[cfg(feature = "arbitrary")]
182impl proptest::arbitrary::Arbitrary for Nibbles {
183 type Parameters = proptest::collection::SizeRange;
184 type Strategy = proptest::strategy::Map<
185 proptest::collection::VecStrategy<core::ops::RangeInclusive<u8>>,
186 fn(Vec<u8>) -> Self,
187 >;
188
189 #[inline]
190 fn arbitrary_with(size: proptest::collection::SizeRange) -> Self::Strategy {
191 use proptest::prelude::*;
192 proptest::collection::vec(0x0..=0xf, size).prop_map(Self::from_nibbles_unchecked)
193 }
194}
195
196#[cfg(feature = "serde")]
197impl serde::Serialize for Nibbles {
198 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
199 where
200 S: serde::Serializer,
201 {
202 if self.is_empty() {
203 serializer.serialize_str("0x")
204 } else {
205 let shifted = self.nibbles >> ((NIBBLES - self.len()) * 4);
206 let hex_str = format!("0x{:0width$x}", shifted, width = self.len());
207 serializer.serialize_str(&hex_str)
208 }
209 }
210}
211
212#[cfg(feature = "serde")]
213impl<'de> serde::Deserialize<'de> for Nibbles {
214 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215 where
216 D: serde::Deserializer<'de>,
217 {
218 let s = alloc::borrow::Cow::<str>::deserialize(deserializer)?;
219
220 let hex_str =
222 s.strip_prefix("0x").ok_or_else(|| serde::de::Error::custom("missing 0x prefix"))?;
223
224 if hex_str.is_empty() {
226 return Ok(Self::new());
227 }
228
229 if hex_str.len() > NIBBLES {
231 return Err(serde::de::Error::custom("hex string too long"));
232 }
233
234 for ch in hex_str.chars() {
237 let _ =
238 ch.to_digit(16).ok_or_else(|| serde::de::Error::custom("invalid hex character"))?;
239 }
240
241 let iter = hex_str.chars().map(|ch| ch.to_digit(16).expect("already validated") as u8);
242 Ok(Self::from_iter_unchecked(iter))
243 }
244}
245
246impl Nibbles {
247 #[inline]
257 pub const fn new() -> Self {
258 Self { length: 0, nibbles: U256::ZERO }
259 }
260
261 pub fn from_iter_unchecked<I>(iter: I) -> Self
276 where
277 I: IntoIterator<Item = u8>,
278 {
279 let mut packed = Self::default();
280 for n in iter {
281 packed.push_unchecked(n);
282 }
283 packed
284 }
285
286 #[inline]
307 #[track_caller]
308 pub fn from_nibbles<T: AsRef<[u8]>>(nibbles: T) -> Self {
309 let bytes = nibbles.as_ref();
310 check_nibbles(bytes);
311 Self::from_iter_unchecked(bytes.iter().copied())
312 }
313
314 #[inline]
337 pub fn from_nibbles_unchecked<T: AsRef<[u8]>>(nibbles: T) -> Self {
338 Self::from_iter_unchecked(nibbles.as_ref().iter().copied())
339 }
340
341 #[inline]
361 #[track_caller]
362 pub fn unpack(data: impl AsRef<[u8]>) -> Self {
363 assert!(data.as_ref().len() <= U256::BYTES);
364 unsafe { Self::unpack_unchecked(data.as_ref()) }
366 }
367
368 pub unsafe fn unpack_unchecked(data: &[u8]) -> Self {
385 let length = data.len() * 2;
386 debug_assert!(length <= NIBBLES);
387
388 cfg_if! {
389 if #[cfg(target_endian = "little")] {
390 let mut nibbles = U256::ZERO;
391 let nibbles_slice = nibbles.as_le_slice_mut();
392 } else {
393 let mut nibbles_slice = [0u8; 32];
394 }
395 }
396
397 let mut src = data.as_ptr().cast::<u8>();
399 let mut dst = nibbles_slice.as_mut_ptr().add(U256::BYTES);
401 for _ in 0..data.len() {
404 dst = dst.sub(1);
405 *dst = *src;
406 src = src.add(1);
407 }
408
409 cfg_if! {
410 if #[cfg(target_endian = "big")] {
411 let nibbles = U256::from_le_bytes(nibbles_slice);
412 }
413 }
414
415 Self { length, nibbles }
416 }
417
418 #[inline]
434 pub fn pack(&self) -> SmallVec<[u8; 32]> {
435 let packed_len = self.len().div_ceil(2);
436 unsafe { smallvec_with(packed_len, |out| self.pack_to_slice_unchecked(out)) }
437 }
438
439 #[inline]
457 #[track_caller]
458 pub fn pack_to(&self, out: &mut [u8]) {
459 assert!(out.len() >= self.len().div_ceil(2));
460 unsafe { self.pack_to_unchecked(out.as_mut_ptr()) }
462 }
463
464 #[inline]
483 pub unsafe fn pack_to_unchecked(&self, ptr: *mut u8) {
484 let slice = slice::from_raw_parts_mut(ptr.cast(), self.len().div_ceil(2));
485 pack_to_unchecked(self, slice);
486 }
487
488 #[inline]
496 pub unsafe fn pack_to_slice_unchecked(&self, out: &mut [MaybeUninit<u8>]) {
497 pack_to_unchecked(self, out)
498 }
499
500 pub fn to_vec(&self) -> Vec<u8> {
510 self.iter().collect()
511 }
512
513 #[inline]
524 pub const fn iter(&self) -> NibblesIter<'_> {
525 NibblesIter { current: 0, nibbles: self }
526 }
527
528 pub fn get_byte(&self, i: usize) -> Option<u8> {
541 if likely((i < usize::MAX) & self.check_index(i.wrapping_add(1))) {
542 Some(self.get_byte_unchecked(i))
543 } else {
544 None
545 }
546 }
547
548 #[inline]
567 #[track_caller]
568 pub fn get_byte_unchecked(&self, i: usize) -> u8 {
569 self.assert_index(i);
570 if i % 2 == 0 {
571 as_le_slice(&self.nibbles)[U256::BYTES - i / 2 - 1]
572 } else {
573 self.get_unchecked(i) << 4 | self.get_unchecked(i + 1)
574 }
575 }
576
577 #[inline]
579 pub fn increment(&self) -> Option<Self> {
580 if self.is_empty() || self.nibbles == SLICE_MASKS[self.len()] {
581 return None;
582 }
583
584 let mut incremented = *self;
585 let add = INCREMENT_VALUES[self.len()];
586 incremented.nibbles += add;
587 Some(incremented)
588 }
589
590 #[inline]
593 pub fn is_leaf(&self) -> bool {
594 self.last() == Some(16)
595 }
596
597 pub fn starts_with(&self, other: &Self) -> bool {
599 if other.len() > self.len() {
601 return false;
602 }
603
604 if other.is_empty() {
606 return true;
607 }
608
609 let mask = SLICE_MASKS[other.len()];
611 (self.nibbles & mask) == other.nibbles
612 }
613
614 pub fn ends_with(&self, other: &Self) -> bool {
616 if other.is_empty() {
618 return true;
619 }
620
621 if other.len() > self.len() {
623 return false;
624 }
625
626 if self.len() % 2 == other.len() % 2 {
628 return as_le_slice(&self.nibbles)
629 [(NIBBLES - self.len()) / 2..(NIBBLES - self.len() + other.len()) / 2]
630 == as_le_slice(&other.nibbles)[(NIBBLES - other.len()) / 2..];
631 }
632
633 let mut i = 0;
634 while i < other.len() {
635 if self.get_unchecked(self.len() - i - 1) != other.get_unchecked(other.len() - i - 1) {
636 return false;
637 }
638 i += 1;
639 }
640
641 true
642 }
643
644 #[inline]
646 pub fn get(&self, i: usize) -> Option<u8> {
647 if self.check_index(i) {
648 Some(self.get_unchecked(i))
649 } else {
650 None
651 }
652 }
653
654 #[inline]
660 #[track_caller]
661 pub fn get_unchecked(&self, i: usize) -> u8 {
662 self.assert_index(i);
663 let byte = as_le_slice(&self.nibbles)[U256::BYTES - i / 2 - 1];
664 if i % 2 == 0 {
665 byte >> 4
666 } else {
667 byte & 0x0F
668 }
669 }
670
671 #[inline]
677 #[track_caller]
678 pub fn set_at(&mut self, i: usize, value: u8) {
679 assert!(self.check_index(i) && value <= 0xf);
680 unsafe { self.set_at_unchecked(i, value) };
682 }
683
684 #[inline]
690 pub unsafe fn set_at_unchecked(&mut self, i: usize, value: u8) {
691 let byte_index = U256::BYTES - i / 2 - 1;
692
693 cfg_if! {
695 if #[cfg(target_endian = "little")] {
696 let byte = unsafe { &mut self.nibbles.as_le_slice_mut()[byte_index] };
697 } else {
698 let mut le_copy = as_le_slice(&self.nibbles);
702 let byte = &mut le_copy.to_mut()[byte_index];
703 }
704 }
705
706 if i % 2 == 0 {
707 *byte = *byte & 0x0f | value << 4;
708 } else {
709 *byte = *byte & 0xf0 | value;
710 }
711
712 #[cfg(target_endian = "big")]
714 {
715 self.nibbles = U256::from_le_slice(&le_copy);
716 }
717 }
718
719 #[inline]
721 pub fn first(&self) -> Option<u8> {
722 self.get(0)
723 }
724
725 #[inline]
727 pub fn last(&self) -> Option<u8> {
728 let len = self.len();
729 if len == 0 {
730 None
731 } else {
732 Some(self.get_unchecked(len - 1))
733 }
734 }
735
736 pub fn common_prefix_length(&self, other: &Self) -> usize {
747 if self.is_empty() || other.is_empty() {
749 return 0;
750 }
751
752 let min_nibble_len = self.len().min(other.len());
753
754 if min_nibble_len <= 16 {
756 let self_limb = self.nibbles.as_limbs()[3];
758 let other_limb = other.nibbles.as_limbs()[3];
759
760 let mask = u64::MAX << ((16 - min_nibble_len) * 4);
762 let xor = (self_limb ^ other_limb) & mask;
763
764 if xor == 0 {
765 return min_nibble_len;
766 } else {
767 return xor.leading_zeros() as usize / 4;
768 }
769 }
770
771 let xor = if min_nibble_len == NIBBLES && self.len() == other.len() {
772 self.nibbles ^ other.nibbles
774 } else {
775 let mask = SLICE_MASKS[min_nibble_len];
777 (self.nibbles ^ other.nibbles) & mask
778 };
779
780 if xor == U256::ZERO {
781 min_nibble_len
782 } else {
783 xor.leading_zeros() / 4
784 }
785 }
786
787 #[inline]
789 const fn bit_len(&self) -> usize {
790 self.len() * 4
791 }
792
793 #[inline]
795 pub const fn is_empty(&self) -> bool {
796 self.len() == 0
797 }
798
799 #[inline]
801 pub const fn len(&self) -> usize {
802 let len = self.length;
803 debug_assert!(len <= 64);
804 unsafe { core::hint::assert_unchecked(len <= 64) };
805 len
806 }
807
808 #[inline]
813 pub fn as_mut_uint_unchecked(&mut self) -> &mut U256 {
814 &mut self.nibbles
815 }
816
817 #[inline]
825 pub fn slice_unchecked(&self, start: usize, end: usize) -> Self {
826 if end == 0 || end <= start {
828 return Self::new();
829 }
830
831 let slice_to_end = end == self.len();
833 if start == 0 && slice_to_end {
834 return *self;
835 }
836
837 let nibble_len = end - start;
838
839 let nibbles = if start == 0 {
841 self.nibbles & SLICE_MASKS[end]
843 } else {
844 let shifted = self.nibbles << (start * 4);
846 if slice_to_end {
847 shifted
849 } else {
850 shifted & SLICE_MASKS[end - start]
852 }
853 };
854
855 Self { length: nibble_len, nibbles }
856 }
857
858 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
864 let start = match range.start_bound() {
866 Bound::Included(&idx) => idx,
867 Bound::Excluded(&idx) => idx + 1,
868 Bound::Unbounded => 0,
869 };
870 let end = match range.end_bound() {
871 Bound::Included(&idx) => idx + 1,
872 Bound::Excluded(&idx) => idx,
873 Bound::Unbounded => self.len(),
874 };
875 assert!(start <= end, "Cannot slice with a start index greater than the end index");
876 assert!(
877 end <= self.len(),
878 "Cannot slice with an end index greater than the length of the nibbles"
879 );
880
881 self.slice_unchecked(start, end)
882 }
883
884 #[inline]
886 pub fn join(&self, other: &Self) -> Self {
887 let mut new = *self;
888 new.extend(other);
889 new
890 }
891
892 #[inline]
898 #[track_caller]
899 pub fn push(&mut self, nibble: u8) {
900 assert!(nibble <= 0xf);
901 self.push_unchecked(nibble);
902 }
903
904 #[inline]
909 pub fn push_unchecked(&mut self, nibble: u8) {
910 let nibble_val = (nibble & 0x0F) as u64;
911 if nibble_val == 0 {
912 self.length += 1;
914 return;
915 }
916
917 let bit_pos = (NIBBLES - self.len() - 1) * 4;
918 let limb_idx = bit_pos / 64;
919 let shift_in_limb = bit_pos % 64;
920
921 unsafe {
923 let limbs = self.nibbles.as_limbs_mut();
924 limbs[limb_idx] |= nibble_val << shift_in_limb;
925 }
926
927 self.length += 1;
928 }
929
930 pub fn pop(&mut self) -> Option<u8> {
932 if self.is_empty() {
933 return None;
934 }
935
936 let shift = (NIBBLES - self.len()) * 4;
938
939 let nibble = (self.nibbles >> shift).as_limbs()[0] as u8 & 0xF;
941
942 let mask_limb_idx = shift / 64;
945 let mask_shift = shift % 64;
946
947 if mask_limb_idx < 4 {
948 unsafe {
950 let limbs = self.nibbles.as_limbs_mut();
951 limbs[mask_limb_idx] &= !(0xF << mask_shift);
952 }
953 }
954
955 self.length -= 1;
956 Some(nibble)
957 }
958
959 pub fn extend(&mut self, other: &Nibbles) {
961 if other.is_empty() {
962 return;
963 }
964
965 self.nibbles |= other.nibbles >> self.bit_len();
966 self.length += other.length;
967 }
968
969 pub fn extend_from_slice(&mut self, other: &[u8]) {
971 assert!(
972 self.length + other.len() * 2 <= NIBBLES,
973 "Cannot extend: resulting length would exceed maximum capacity"
974 );
975 self.extend_from_slice_unchecked(other);
976 }
977
978 pub fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
985 if other.is_empty() {
986 return;
987 }
988
989 let len_bytes = other.len();
990 let mut other = U256::from_be_slice(other);
991 if len_bytes > 0 {
992 other <<= (U256::BYTES - len_bytes) * 8;
993 }
994 self.nibbles |= other >> self.bit_len();
995 self.length += len_bytes * 2;
996 }
997
998 #[inline]
1000 pub fn truncate(&mut self, new_len: usize) {
1001 assert!(
1002 new_len <= self.len(),
1003 "Cannot truncate to a length greater than the current length"
1004 );
1005 *self = self.slice_unchecked(0, new_len);
1006 }
1007
1008 #[inline]
1010 pub fn clear(&mut self) {
1011 *self = Self::new();
1012 }
1013
1014 #[inline]
1016 const fn check_index(&self, i: usize) -> bool {
1017 i < self.len()
1018 }
1019
1020 #[inline]
1022 fn assert_index(&self, i: usize) {
1023 let len = self.len();
1024 if i >= len {
1025 panic_invalid_index(len, i);
1026 }
1027 }
1028}
1029
1030#[derive(Debug, Clone)]
1044pub struct NibblesIter<'a> {
1045 current: usize,
1047 nibbles: &'a Nibbles,
1049}
1050
1051impl<'a> Iterator for NibblesIter<'a> {
1052 type Item = u8;
1053
1054 #[inline]
1055 fn next(&mut self) -> Option<Self::Item> {
1056 self.nibbles.get(self.current).inspect(|_| self.current += 1)
1057 }
1058
1059 #[inline]
1060 fn size_hint(&self) -> (usize, Option<usize>) {
1061 let len = self.len();
1062 (len, Some(len))
1063 }
1064}
1065
1066impl<'a> ExactSizeIterator for NibblesIter<'a> {
1067 #[inline]
1068 fn len(&self) -> usize {
1069 self.nibbles.len() - self.current
1070 }
1071}
1072
1073#[inline]
1079unsafe fn pack_to_unchecked(nibbles: &Nibbles, out: &mut [MaybeUninit<u8>]) {
1080 let byte_len = nibbles.len().div_ceil(2);
1081 debug_assert!(out.len() >= byte_len);
1082 let sl = as_le_slice(&nibbles.nibbles);
1084 let mut src = sl.as_ptr().add(U256::BYTES);
1085 let mut dst = out.as_mut_ptr().cast::<u8>();
1087 for _ in 0..byte_len {
1090 src = src.sub(1);
1091 *dst = *src;
1092 dst = dst.add(1);
1093 }
1094}
1095
1096#[inline]
1104pub unsafe fn smallvec_with<const N: usize>(
1105 len: usize,
1106 f: impl FnOnce(&mut [MaybeUninit<u8>]),
1107) -> SmallVec<[u8; N]> {
1108 let mut buf = smallvec_with_len::<N>(len);
1109 f(unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr().cast(), len) });
1110 buf
1111}
1112
1113#[inline]
1114#[allow(clippy::uninit_vec)]
1115unsafe fn smallvec_with_len<const N: usize>(len: usize) -> SmallVec<[u8; N]> {
1116 if likely(len <= N) {
1117 SmallVec::from_buf_and_len_unchecked(MaybeUninit::<[u8; N]>::uninit(), len)
1118 } else {
1119 let mut vec = Vec::with_capacity(len);
1120 unsafe { vec.set_len(len) };
1121 SmallVec::from_vec(vec)
1122 }
1123}
1124
1125#[inline]
1126#[track_caller]
1127fn check_nibbles(nibbles: &[u8]) {
1128 if !valid_nibbles(nibbles) {
1129 panic_invalid_nibbles();
1130 }
1131}
1132
1133fn valid_nibbles(nibbles: &[u8]) -> bool {
1134 nibbles.iter().all(|&nibble| nibble <= 0xf)
1135}
1136
1137#[cold]
1138#[inline(never)]
1139#[cfg_attr(debug_assertions, track_caller)]
1140const fn panic_invalid_nibbles() -> ! {
1141 panic!("attempted to create invalid nibbles");
1142}
1143
1144#[cold]
1145#[inline(never)]
1146#[cfg_attr(debug_assertions, track_caller)]
1147fn panic_invalid_index(len: usize, i: usize) -> ! {
1148 panic!("index out of bounds: {i} for nibbles of length {len}");
1149}
1150
1151enum ByteContainer<'a, const N: usize> {
1153 #[cfg_attr(target_endian = "big", allow(unused))]
1155 Borrowed(&'a [u8]),
1156 #[cfg_attr(target_endian = "little", allow(unused))]
1158 Owned([u8; N]),
1159}
1160
1161impl<'a, const N: usize> ByteContainer<'a, N> {
1162 #[cfg_attr(target_endian = "little", allow(unused))]
1168 pub(crate) fn to_mut(&mut self) -> &mut [u8; N] {
1169 match self {
1170 ByteContainer::Borrowed(slice) => {
1171 let mut array = [0u8; N];
1172 array[..N].copy_from_slice(&slice[..N]);
1173 *self = ByteContainer::Owned(array);
1174 self.to_mut()
1175 }
1176 ByteContainer::Owned(ref mut array) => array,
1177 }
1178 }
1179}
1180
1181impl<'a, const N: usize> Deref for ByteContainer<'a, N> {
1182 type Target = [u8];
1183
1184 fn deref(&self) -> &Self::Target {
1185 match self {
1186 ByteContainer::Borrowed(slice) => slice,
1187 ByteContainer::Owned(array) => array.as_slice(),
1188 }
1189 }
1190}
1191
1192#[inline]
1194const fn as_le_slice(x: &U256) -> ByteContainer<'_, { U256::BYTES }> {
1195 cfg_if! {
1196 if #[cfg(target_endian = "little")] {
1197 ByteContainer::Borrowed(x.as_le_slice())
1198 } else {
1199 ByteContainer::Owned(x.to_le_bytes())
1200 }
1201 }
1202}
1203
1204#[cfg(test)]
1205mod tests {
1206 use super::*;
1207
1208 #[test]
1209 fn pack() {
1210 let tests = [
1211 (&[][..], &[][..]),
1212 (&[0xa], &[0xa0]),
1213 (&[0xa, 0x0], &[0xa0]),
1214 (&[0xa, 0xb], &[0xab]),
1215 (&[0xa, 0xb, 0x2], &[0xab, 0x20]),
1216 (&[0xa, 0xb, 0x2, 0x0], &[0xab, 0x20]),
1217 (&[0xa, 0xb, 0x2, 0x7], &[0xab, 0x27]),
1218 ];
1219 for (input, expected) in tests {
1220 assert!(valid_nibbles(input));
1221 let nibbles = Nibbles::from_nibbles(input);
1222 let encoded = nibbles.pack();
1223 assert_eq!(
1224 &encoded[..],
1225 expected,
1226 "input: {input:x?}, expected: {expected:x?}, got: {encoded:x?}",
1227 );
1228 }
1229 }
1230
1231 #[test]
1232 fn get_unchecked() {
1233 for len in 0..NIBBLES {
1234 let raw = (0..16).cycle().take(len).collect::<Vec<u8>>();
1235 let nibbles = Nibbles::from_nibbles(&raw);
1236 for (i, raw_nibble) in raw.into_iter().enumerate() {
1237 assert_eq!(nibbles.get_unchecked(i), raw_nibble);
1238 }
1239 }
1240 }
1241
1242 #[test]
1243 fn set_at_unchecked() {
1244 for len in 0..=NIBBLES {
1245 let raw = (0..16).cycle().take(len).collect::<Vec<u8>>();
1246 let mut nibbles = Nibbles::from_nibbles(&raw);
1247 for (i, raw_nibble) in raw.iter().enumerate() {
1248 let new_nibble = (raw_nibble + 1) % 16;
1249 unsafe { nibbles.set_at_unchecked(i, new_nibble) };
1250
1251 let mut new_raw_nibbles = nibbles.clone().to_vec();
1252 new_raw_nibbles[i] = new_nibble;
1253 let new_nibbles = Nibbles::from_nibbles(&new_raw_nibbles);
1254 assert_eq!(nibbles, new_nibbles,);
1255 }
1256 }
1257 }
1258
1259 #[test]
1260 fn push_pop() {
1261 let mut nibbles = Nibbles::new();
1262 nibbles.push(0x0A);
1263 assert_eq!(nibbles.get_unchecked(0), 0x0A);
1264 assert_eq!(nibbles.len(), 1);
1265
1266 assert_eq!(nibbles.pop(), Some(0x0A));
1267 assert_eq!(nibbles.len(), 0);
1268 }
1269
1270 #[test]
1271 fn get_byte() {
1272 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1273 assert_eq!(nibbles.get_byte(0), Some(0xAB));
1274 assert_eq!(nibbles.get_byte(1), Some(0xBC));
1275 assert_eq!(nibbles.get_byte(2), Some(0xCD));
1276 assert_eq!(nibbles.get_byte(3), None);
1277 assert_eq!(nibbles.get_byte(usize::MAX), None);
1278 }
1279
1280 #[test]
1281 fn get_byte_unchecked() {
1282 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1283 assert_eq!(nibbles.get_byte_unchecked(0), 0xAB);
1284 assert_eq!(nibbles.get_byte_unchecked(1), 0xBC);
1285 assert_eq!(nibbles.get_byte_unchecked(2), 0xCD);
1286 }
1287
1288 #[test]
1289 fn clone() {
1290 let a = Nibbles::from_nibbles([1, 2, 3]);
1291 #[allow(clippy::redundant_clone)]
1292 let b = a;
1293 assert_eq!(a, b);
1294 }
1295
1296 #[test]
1297 fn ord() {
1298 let nibbles1 = Nibbles::default();
1300 let nibbles2 = Nibbles::default();
1301 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Equal);
1302
1303 let nibbles1 = Nibbles::default();
1305 let nibbles2 = Nibbles::from_nibbles([0]);
1306 assert_eq!(nibbles2.cmp(&nibbles1), Ordering::Greater);
1307
1308 let nibbles1 = Nibbles::unpack([0x12, 0x34]);
1310 let nibbles2 = Nibbles::unpack([0x12, 0x34]);
1311 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Equal);
1312
1313 let short = Nibbles::unpack([0x12]);
1315 let long = Nibbles::unpack([0x12, 0x34]);
1316 assert_eq!(short.cmp(&long), Ordering::Less);
1317
1318 let nibbles1 = Nibbles::unpack([0x12, 0x34]);
1320 let nibbles2 = Nibbles::unpack([0x12, 0x35]);
1321 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1322
1323 let nibbles1 = Nibbles::unpack([0x12, 0x34]);
1325 let nibbles2 = Nibbles::unpack([0x13, 0x34]);
1326 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1327
1328 let nibbles1 = Nibbles::unpack([0x1]);
1330 let nibbles2 = Nibbles::unpack([0x2]);
1331 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1332
1333 let odd = Nibbles::unpack([0x1]);
1335 let even = Nibbles::unpack([0x12]);
1336 assert_eq!(odd.cmp(&even), Ordering::Less);
1337
1338 let nibbles1 = Nibbles::unpack([0x12, 0x34, 0x56, 0x78]);
1340 let nibbles2 = Nibbles::unpack([0x12, 0x34, 0x56, 0x79]);
1341 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1342
1343 let nibbles1 = Nibbles::from_nibbles([0x0, 0x0]);
1344 let nibbles2 = Nibbles::from_nibbles([0x1]);
1345 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1346
1347 let nibbles1 = Nibbles::from_nibbles([0x1]);
1348 let nibbles2 = Nibbles::from_nibbles([0x0, 0x2]);
1349 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Greater);
1350
1351 let nibbles1 = Nibbles::from_nibbles([vec![0; 61], vec![1; 1], vec![0; 1]].concat());
1352 let nibbles2 = Nibbles::from_nibbles([vec![0; 61], vec![1; 1], vec![0; 2]].concat());
1353 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1354 }
1355
1356 #[test]
1357 fn starts_with() {
1358 let nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1359
1360 let empty = Nibbles::default();
1362 assert!(nibbles.starts_with(&empty));
1363 assert!(empty.starts_with(&empty));
1364 assert!(!empty.starts_with(&nibbles));
1365
1366 assert!(nibbles.starts_with(&nibbles));
1368
1369 let prefix = Nibbles::from_nibbles([1, 2]);
1371 assert!(nibbles.starts_with(&prefix));
1372 assert!(!prefix.starts_with(&nibbles));
1373
1374 let different = Nibbles::from_nibbles([2, 2, 3, 4]);
1376 assert!(!nibbles.starts_with(&different));
1377
1378 let longer = Nibbles::from_nibbles([1, 2, 3, 4, 5, 6]);
1380 assert!(!nibbles.starts_with(&longer));
1381
1382 let even_nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1384 let odd_prefix = Nibbles::from_nibbles([1, 2, 3]);
1385 assert!(even_nibbles.starts_with(&odd_prefix));
1386
1387 let odd_nibbles = Nibbles::from_nibbles([1, 2, 3]);
1389 let even_prefix = Nibbles::from_nibbles([1, 2]);
1390 assert!(odd_nibbles.starts_with(&even_prefix));
1391 }
1392
1393 #[test]
1394 fn ends_with() {
1395 let nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1396
1397 let empty = Nibbles::default();
1399 assert!(nibbles.ends_with(&empty));
1400 assert!(empty.ends_with(&empty));
1401 assert!(!empty.ends_with(&nibbles));
1402
1403 assert!(nibbles.ends_with(&nibbles));
1405
1406 let suffix = Nibbles::from_nibbles([3, 4]);
1408 assert!(nibbles.ends_with(&suffix));
1409 assert!(!suffix.ends_with(&nibbles));
1410
1411 let different = Nibbles::from_nibbles([2, 3, 5]);
1413 assert!(!nibbles.ends_with(&different));
1414
1415 let longer = Nibbles::from_nibbles([2, 3, 4, 5, 6]);
1417 assert!(!nibbles.ends_with(&longer));
1418
1419 let even_nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1421 let odd_suffix = Nibbles::from_nibbles([2, 3, 4]);
1422 assert!(even_nibbles.ends_with(&odd_suffix));
1423
1424 let odd_nibbles = Nibbles::from_nibbles([1, 2, 3]);
1426 let even_suffix = Nibbles::from_nibbles([2, 3]);
1427 assert!(odd_nibbles.ends_with(&even_suffix));
1428 }
1429
1430 #[test]
1431 fn slice() {
1432 let empty = Nibbles::default();
1434 assert_eq!(empty.slice(..), empty);
1435
1436 let even = Nibbles::from_nibbles([0, 1, 2, 3, 4, 5]);
1438
1439 assert_eq!(even.slice(..), even);
1441 assert_eq!(even.slice(0..6), even);
1442
1443 assert_eq!(even.slice(3..3), Nibbles::default());
1445
1446 assert_eq!(even.slice(0..2), Nibbles::from_iter(0..2));
1448
1449 assert_eq!(even.slice(2..4), Nibbles::from_iter(2..4));
1451
1452 assert_eq!(even.slice(4..6), Nibbles::from_iter(4..6));
1454
1455 let odd = Nibbles::from_iter(0..5);
1457
1458 assert_eq!(odd.slice(..), odd);
1460 assert_eq!(odd.slice(0..5), odd);
1461
1462 assert_eq!(odd.slice(0..3), Nibbles::from_iter(0..3));
1464
1465 assert_eq!(odd.slice(1..4), Nibbles::from_iter(1..4));
1467
1468 assert_eq!(odd.slice(1..3), Nibbles::from_iter(1..3));
1470
1471 assert_eq!(odd.slice(2..5), Nibbles::from_iter(2..5));
1473
1474 assert_eq!(odd.slice(1..4), Nibbles::from_iter(1..4));
1476
1477 assert_eq!(even.slice(2..3), Nibbles::from_iter(2..3));
1479
1480 assert_eq!(even.slice(3..4), Nibbles::from_iter(3..4));
1481
1482 assert_eq!(even.slice(2..), Nibbles::from_iter(2..6));
1484 assert_eq!(even.slice(..4), Nibbles::from_iter(0..4));
1485 assert_eq!(even.slice(..=3), Nibbles::from_iter(0..4));
1486
1487 assert_eq!(
1489 Nibbles::from_iter((0..16).cycle().take(64)).slice(1..),
1490 Nibbles::from_iter((0..16).cycle().take(64).skip(1))
1491 );
1492 }
1493
1494 #[test]
1495 fn common_prefix_length() {
1496 let empty = Nibbles::default();
1498 assert_eq!(empty.common_prefix_length(&empty), 0);
1499
1500 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1502 let nibbles2 = Nibbles::from_nibbles([1, 2, 3, 4]);
1503 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 4);
1504 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 4);
1505
1506 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1508 let nibbles2 = Nibbles::from_nibbles([1, 2, 5, 6]);
1509 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 2);
1510 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 2);
1511
1512 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1514 let nibbles2 = Nibbles::from_nibbles([1, 2, 3, 7]);
1515 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 3);
1516 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 3);
1517
1518 let nibbles1 = Nibbles::from_nibbles([5, 6, 7, 8]);
1520 let nibbles2 = Nibbles::from_nibbles([1, 2, 3, 4]);
1521 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 0);
1522 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 0);
1523
1524 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4, 5, 6]);
1526 let nibbles2 = Nibbles::from_nibbles([1, 2, 3]);
1527 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 3);
1528 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 3);
1529
1530 let nibbles1 = Nibbles::from_nibbles([1, 2, 3]);
1532 let nibbles2 = Nibbles::from_nibbles([1, 2, 7]);
1533 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 2);
1534 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 2);
1535
1536 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1538 let nibbles2 = Nibbles::from_nibbles([5, 2, 3, 4]);
1539 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 0);
1540 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 0);
1541
1542 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1544 assert_eq!(nibbles1.common_prefix_length(&empty), 0);
1545 assert_eq!(empty.common_prefix_length(&nibbles1), 0);
1546
1547 let nibbles1 =
1549 Nibbles::from_nibbles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]);
1550 let nibbles2 =
1551 Nibbles::from_nibbles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1]);
1552 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 15);
1553 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 15);
1554
1555 let nibbles1 =
1557 Nibbles::from_nibbles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]);
1558 let nibbles2 = Nibbles::from_nibbles([
1559 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1560 11, 12, 13, 14, 15, 0,
1561 ]);
1562 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 16);
1563 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 16);
1564
1565 let nibbles1 = Nibbles::from_nibbles([
1567 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1568 11, 12, 13, 14, 15, 0,
1569 ]);
1570 let nibbles2 = Nibbles::from_nibbles([
1571 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1572 11, 12, 13, 14, 15, 1,
1573 ]);
1574 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 31);
1575 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 31);
1576
1577 let nibbles1 = Nibbles::from_nibbles([
1579 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1580 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
1581 ]);
1582 let nibbles2 = Nibbles::from_nibbles([
1583 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1584 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1,
1585 ]);
1586 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 47);
1587 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 47);
1588
1589 let nibbles1 = Nibbles::from_nibbles([
1591 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1592 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3,
1593 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
1594 ]);
1595 let nibbles2 = Nibbles::from_nibbles([
1596 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
1597 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3,
1598 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1,
1599 ]);
1600 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 63);
1601 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 63);
1602
1603 let current = Nibbles::from_nibbles([0u8; 64]);
1604 let path = Nibbles::from_nibbles([vec![0u8; 63], vec![2u8]].concat());
1605 assert_eq!(current.common_prefix_length(&path), 63);
1606
1607 let current = Nibbles::from_nibbles([0u8; 63]);
1608 let path = Nibbles::from_nibbles([vec![0u8; 62], vec![1u8], vec![0u8]].concat());
1609 assert_eq!(current.common_prefix_length(&path), 62);
1610 }
1611
1612 #[test]
1613 fn truncate() {
1614 let mut nibbles = Nibbles::default();
1616 nibbles.truncate(0);
1617 assert_eq!(nibbles, Nibbles::default());
1618
1619 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1621 nibbles.truncate(0);
1622 assert_eq!(nibbles, Nibbles::default());
1623
1624 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1626 nibbles.truncate(4);
1627 assert_eq!(nibbles, Nibbles::from_nibbles([1, 2, 3, 4]));
1628
1629 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1631 nibbles.truncate(2);
1632 assert_eq!(nibbles, Nibbles::from_nibbles([1, 2]));
1633
1634 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1636 nibbles.truncate(2);
1637 assert_eq!(nibbles, Nibbles::from_nibbles([1, 2]));
1638
1639 let mut nibbles = Nibbles::from_nibbles([5, 6, 7, 8]);
1641 nibbles.truncate(1);
1642 assert_eq!(nibbles, Nibbles::from_nibbles([5]));
1643 }
1644
1645 #[test]
1646 fn push_unchecked() {
1647 let mut nibbles = Nibbles::default();
1649 nibbles.push_unchecked(0x5);
1650 assert_eq!(nibbles, Nibbles::from_nibbles([0x5]));
1651
1652 nibbles.push_unchecked(0xA);
1654 assert_eq!(nibbles, Nibbles::from_nibbles([0x5, 0xA]));
1655
1656 let mut nibbles = Nibbles::default();
1658 for nibble in [0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8] {
1659 nibbles.push_unchecked(nibble);
1660 }
1661 assert_eq!(nibbles, Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]));
1662
1663 let mut nibbles = Nibbles::default();
1665 nibbles.push_unchecked(0xFF); nibbles.push_unchecked(0x1A); nibbles.push_unchecked(0x25); assert_eq!(nibbles, Nibbles::from_nibbles([0xF, 0xA, 0x5]));
1669
1670 let mut nibbles = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
1672 nibbles.push_unchecked(0x4);
1673 assert_eq!(nibbles, Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]));
1674
1675 let mut nibbles = Nibbles::default();
1677 nibbles.push_unchecked(0x0);
1678 nibbles.push_unchecked(0xF);
1679 assert_eq!(nibbles, Nibbles::from_nibbles([0x0, 0xF]));
1680
1681 let mut nibbles = Nibbles::default();
1683 let test_sequence: Vec<u8> = (0..32).map(|i| i % 16).collect();
1684 for &nibble in &test_sequence {
1685 nibbles.push_unchecked(nibble);
1686 }
1687 assert_eq!(nibbles, Nibbles::from_nibbles(test_sequence));
1688 }
1689
1690 #[test]
1691 fn unpack() {
1692 for (test_idx, bytes) in (0..=32).map(|i| vec![0xFF; i]).enumerate() {
1693 let packed_nibbles = Nibbles::unpack(&bytes);
1694 let nibbles = Nibbles::unpack(&bytes);
1695
1696 assert_eq!(
1697 packed_nibbles.len(),
1698 nibbles.len(),
1699 "Test case {test_idx}: Length mismatch for bytes {bytes:?}",
1700 );
1701 assert_eq!(
1702 packed_nibbles.len(),
1703 bytes.len() * 2,
1704 "Test case {test_idx}: Expected length to be 2x byte length",
1705 );
1706
1707 for i in 0..packed_nibbles.len() {
1709 assert_eq!(
1710 packed_nibbles.get_unchecked(i),
1711 nibbles.get_unchecked(i),
1712 "Test case {}: Nibble at index {} differs for bytes {:?}: Nibbles={:?}, Nibbles={:?}",
1713 test_idx,
1714 i,
1715 bytes,
1716 packed_nibbles.get_unchecked(i),
1717 nibbles.get_unchecked(i)
1718 );
1719 }
1720 }
1721
1722 let nibbles = Nibbles::unpack([0xAB, 0xCD]);
1723 assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);
1724 }
1725
1726 #[test]
1727 fn increment() {
1728 assert_eq!(
1730 Nibbles::from_nibbles([0x0, 0x0, 0x0]).increment().unwrap(),
1731 Nibbles::from_nibbles([0x0, 0x0, 0x1])
1732 );
1733
1734 assert_eq!(
1736 Nibbles::from_nibbles([0x0, 0x0, 0xF]).increment().unwrap(),
1737 Nibbles::from_nibbles([0x0, 0x1, 0x0])
1738 );
1739
1740 assert_eq!(
1742 Nibbles::from_nibbles([0x0, 0xF, 0xF]).increment().unwrap(),
1743 Nibbles::from_nibbles([0x1, 0x0, 0x0])
1744 );
1745
1746 assert_eq!(
1748 Nibbles::from_nibbles([0xE, 0xF, 0xF]).increment().unwrap(),
1749 Nibbles::from_nibbles([0xF, 0x0, 0x0])
1750 );
1751
1752 assert_eq!(Nibbles::from_nibbles([0xF, 0xF, 0xF]).increment(), None);
1754
1755 assert_eq!(Nibbles::new().increment(), None);
1757
1758 assert_eq!(Nibbles::from_nibbles([0x5]).increment().unwrap(), Nibbles::from_nibbles([0x6]));
1760
1761 assert_eq!(Nibbles::from_nibbles([0xF]).increment(), None);
1763
1764 assert_eq!(
1766 Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x5]).increment().unwrap(),
1767 Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x6])
1768 );
1769
1770 assert_eq!(
1772 Nibbles::from_nibbles([0x1, 0x2, 0x3, 0xF, 0xF]).increment().unwrap(),
1773 Nibbles::from_nibbles([0x1, 0x2, 0x4, 0x0, 0x0])
1774 );
1775 }
1776
1777 #[test]
1778 fn iter() {
1779 let empty = Nibbles::new();
1781 assert!(empty.iter().collect::<Vec<_>>().is_empty());
1782
1783 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1785 let collected: Vec<u8> = nibbles.iter().collect();
1786 assert_eq!(collected, vec![0x0A, 0x0B, 0x0C, 0x0D]);
1787
1788 assert_eq!(nibbles.iter().collect::<Vec<_>>(), nibbles.to_vec());
1790
1791 let single = Nibbles::from_nibbles([0x05]);
1793 assert_eq!(single.iter().collect::<Vec<_>>(), vec![0x05]);
1794
1795 let odd = Nibbles::from_nibbles([0x01, 0x02, 0x03]);
1797 assert_eq!(odd.iter().collect::<Vec<_>>(), vec![0x01, 0x02, 0x03]);
1798
1799 let max_nibbles: Vec<u8> = (0..64).map(|i| (i % 16) as u8).collect();
1801 let max = Nibbles::from_nibbles(&max_nibbles);
1802 assert_eq!(max.iter().collect::<Vec<_>>(), max_nibbles);
1803
1804 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1806 let mut iter = nibbles.iter();
1807 assert_eq!(iter.len(), 4);
1808 assert_eq!(iter.size_hint(), (4, Some(4)));
1809
1810 iter.next();
1811 assert_eq!(iter.len(), 3);
1812 assert_eq!(iter.size_hint(), (3, Some(3)));
1813
1814 iter.next();
1815 iter.next();
1816 assert_eq!(iter.len(), 1);
1817 assert_eq!(iter.size_hint(), (1, Some(1)));
1818
1819 iter.next();
1820 assert_eq!(iter.len(), 0);
1821 assert_eq!(iter.size_hint(), (0, Some(0)));
1822 assert_eq!(iter.next(), None);
1823
1824 let nibbles = Nibbles::from_nibbles([0x01, 0x02, 0x03, 0x04]);
1826 let mut iter1 = nibbles.iter();
1827 iter1.next();
1828 let iter2 = iter1.clone();
1829
1830 assert_eq!(iter1.collect::<Vec<_>>(), vec![0x02, 0x03, 0x04]);
1831 assert_eq!(iter2.collect::<Vec<_>>(), vec![0x02, 0x03, 0x04]);
1832 }
1833
1834 #[cfg(feature = "arbitrary")]
1835 mod arbitrary {
1836 use super::*;
1837 use proptest::{collection::vec, prelude::*};
1838
1839 proptest::proptest! {
1840 #[test]
1841 #[cfg_attr(miri, ignore = "no proptest")]
1842 fn pack_unpack_roundtrip(input in vec(any::<u8>(), 0..32)) {
1843 let nibbles = Nibbles::unpack(&input);
1844 prop_assert!(valid_nibbles(&nibbles.to_vec()));
1845 let packed = nibbles.pack();
1846 prop_assert_eq!(&packed[..], input);
1847 }
1848 }
1849 }
1850
1851 #[cfg(feature = "serde")]
1852 mod serde_tests {
1853 use super::*;
1854 use crate::alloc::string::ToString;
1855
1856 #[test]
1857 fn serde_empty() {
1858 let nibbles = Nibbles::new();
1859 let serialized = serde_json::to_string(&nibbles).unwrap();
1860 assert_eq!(serialized, r#""0x""#);
1861
1862 let deserialized: Nibbles = serde_json::from_str(&serialized).unwrap();
1863 assert_eq!(deserialized, nibbles);
1864 }
1865
1866 #[test]
1867 fn serde_single_nibble() {
1868 let nibbles = Nibbles::from_nibbles([0x5]);
1869 let serialized = serde_json::to_string(&nibbles).unwrap();
1870 assert_eq!(serialized, r#""0x5""#);
1871
1872 let deserialized: Nibbles = serde_json::from_str(&serialized).unwrap();
1873 assert_eq!(deserialized, nibbles);
1874 }
1875
1876 #[test]
1877 fn serde_multiple_nibbles() {
1878 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1879 let serialized = serde_json::to_string(&nibbles).unwrap();
1880 assert_eq!(serialized, r#""0xabcd""#);
1881
1882 let deserialized: Nibbles = serde_json::from_str(&serialized).unwrap();
1883 assert_eq!(deserialized, nibbles);
1884 }
1885
1886 #[test]
1887 fn serde_odd_nibbles() {
1888 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C]);
1889 let serialized = serde_json::to_string(&nibbles).unwrap();
1890 assert_eq!(serialized, r#""0xabc""#);
1891
1892 let deserialized: Nibbles = serde_json::from_str(&serialized).unwrap();
1893 assert_eq!(deserialized, nibbles);
1894 }
1895
1896 #[test]
1897 fn serde_leading_zeros() {
1898 let nibbles = Nibbles::from_nibbles([0x0, 0x0, 0x1, 0x2]);
1899 let serialized = serde_json::to_string(&nibbles).unwrap();
1900 assert_eq!(serialized, r#""0x0012""#);
1901
1902 let deserialized: Nibbles = serde_json::from_str(&serialized).unwrap();
1903 assert_eq!(deserialized, nibbles);
1904 }
1905
1906 #[test]
1907 fn serde_max_nibbles() {
1908 let nibbles = Nibbles::from_nibbles([0xF; 64]);
1909 let serialized = serde_json::to_string(&nibbles).unwrap();
1910 assert_eq!(
1911 serialized,
1912 r#""0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff""#
1913 );
1914
1915 let deserialized: Nibbles = serde_json::from_str(&serialized).unwrap();
1916 assert_eq!(deserialized, nibbles);
1917 }
1918
1919 #[test]
1920 fn deserialize_missing_prefix() {
1921 let result: Result<Nibbles, _> = serde_json::from_str(r#""abcd""#);
1922 assert!(result.is_err());
1923 assert!(result.unwrap_err().to_string().contains("missing 0x prefix"));
1924 }
1925
1926 #[test]
1927 fn deserialize_invalid_hex() {
1928 let result: Result<Nibbles, _> = serde_json::from_str(r#""0xghij""#);
1929 assert!(result.is_err());
1930 assert!(result.unwrap_err().to_string().contains("invalid hex character"));
1931 }
1932
1933 #[test]
1934 fn deserialize_too_long() {
1935 let too_long = format!(r#""0x{}""#, "f".repeat(65));
1936 let result: Result<Nibbles, _> = serde_json::from_str(&too_long);
1937 assert!(result.is_err());
1938 assert!(result.unwrap_err().to_string().contains("hex string too long"));
1939 }
1940
1941 #[test]
1942 fn serde_from_object() {
1943 #[derive(serde::Serialize, serde::Deserialize)]
1945 struct TestStruct {
1946 nibbles: Nibbles,
1947 }
1948
1949 let original = TestStruct { nibbles: Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]) };
1950 let json = serde_json::to_string(&original).unwrap();
1951 let deserialized: TestStruct = serde_json::from_str(&json).unwrap();
1952 assert_eq!(deserialized.nibbles, original.nibbles);
1953 }
1954
1955 #[test]
1956 fn serde_from_parsed_value() {
1957 let json_str = r#"{"nibbles": "0xabcd"}"#;
1959 let value: serde_json::Value = serde_json::from_str(json_str).unwrap();
1960 let nibbles: Nibbles = serde_json::from_value(value["nibbles"].clone()).unwrap();
1961 assert_eq!(nibbles, Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]));
1962 }
1963 }
1964}