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)]
89#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
90pub struct Nibbles {
91 pub(crate) length: usize,
95 pub(crate) nibbles: U256,
98}
99
100impl fmt::Debug for Nibbles {
101 #[inline]
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 if self.is_empty() {
104 write!(f, "Nibbles(0x)")
105 } else {
106 let shifted = self.nibbles >> ((NIBBLES - self.len()) * 4);
107 write!(f, "Nibbles(0x{:0width$x})", shifted, width = self.len())
108 }
109 }
110}
111
112#[cfg(feature = "arbitrary")]
113impl<'a> arbitrary::Arbitrary<'a> for Nibbles {
114 fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
115 let length = u.int_in_range(0..=NIBBLES)?;
116 let nibbles = Nibbles::from_nibbles_unchecked(
117 (0..length).map(|_| u.int_in_range(0..=0xf)).collect::<Result<Vec<_>, _>>()?,
118 );
119 Ok(nibbles)
120 }
121}
122
123impl Ord for Nibbles {
127 #[inline]
128 fn cmp(&self, other: &Self) -> Ordering {
129 let self_len = self.len().div_ceil(2);
130 let other_len = other.len().div_ceil(2);
131 let l = cmp::min(self_len, other_len);
132
133 let lhs = &as_le_slice(&self.nibbles)[U256::BYTES - l..];
136 let rhs = &as_le_slice(&other.nibbles)[U256::BYTES - l..];
137
138 for i in (0..l).rev() {
139 match lhs[i].cmp(&rhs[i]) {
140 Ordering::Equal => (),
141 non_eq => return non_eq,
142 }
143 }
144
145 self.len().cmp(&other.len())
146 }
147}
148
149impl PartialOrd for Nibbles {
150 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
151 Some(self.cmp(other))
152 }
153}
154
155impl FromIterator<u8> for Nibbles {
156 fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
157 let mut nibbles = Self::default();
158 for n in iter {
159 nibbles.push(n);
160 }
161 nibbles
162 }
163}
164
165#[cfg(feature = "rlp")]
166impl alloy_rlp::Encodable for Nibbles {
167 #[inline]
168 fn encode(&self, out: &mut dyn alloy_rlp::BufMut) {
169 alloy_rlp::Header { list: true, payload_length: self.len() }.encode(out);
170 for i in 0..self.len() {
171 self.get_unchecked(i).encode(out);
172 }
173 }
174
175 #[inline]
176 fn length(&self) -> usize {
177 let payload_length = self.len();
178 payload_length + alloy_rlp::length_of_length(payload_length)
179 }
180}
181
182#[cfg(feature = "arbitrary")]
183impl proptest::arbitrary::Arbitrary for Nibbles {
184 type Parameters = proptest::collection::SizeRange;
185 type Strategy = proptest::strategy::Map<
186 proptest::collection::VecStrategy<core::ops::RangeInclusive<u8>>,
187 fn(Vec<u8>) -> Self,
188 >;
189
190 #[inline]
191 fn arbitrary_with(size: proptest::collection::SizeRange) -> Self::Strategy {
192 use proptest::prelude::*;
193 proptest::collection::vec(0x0..=0xf, size).prop_map(Self::from_nibbles_unchecked)
194 }
195}
196
197impl Nibbles {
198 #[inline]
208 pub const fn new() -> Self {
209 Self { length: 0, nibbles: U256::ZERO }
210 }
211
212 pub fn from_iter_unchecked<I>(iter: I) -> Self
227 where
228 I: IntoIterator<Item = u8>,
229 {
230 let mut packed = Self::default();
231 for n in iter {
232 packed.push_unchecked(n);
233 }
234 packed
235 }
236
237 #[inline]
258 #[track_caller]
259 pub fn from_nibbles<T: AsRef<[u8]>>(nibbles: T) -> Self {
260 let bytes = nibbles.as_ref();
261 check_nibbles(bytes);
262 Self::from_iter_unchecked(bytes.iter().copied())
263 }
264
265 #[inline]
288 pub fn from_nibbles_unchecked<T: AsRef<[u8]>>(nibbles: T) -> Self {
289 Self::from_iter_unchecked(nibbles.as_ref().iter().copied())
290 }
291
292 #[inline]
312 #[track_caller]
313 pub fn unpack(data: impl AsRef<[u8]>) -> Self {
314 assert!(data.as_ref().len() <= U256::BYTES);
315 unsafe { Self::unpack_unchecked(data.as_ref()) }
317 }
318
319 pub unsafe fn unpack_unchecked(data: &[u8]) -> Self {
336 let length = data.len() * 2;
337 debug_assert!(length <= NIBBLES);
338
339 cfg_if! {
340 if #[cfg(target_endian = "little")] {
341 let mut nibbles = U256::ZERO;
342 let nibbles_slice = nibbles.as_le_slice_mut();
343 } else {
344 let mut nibbles_slice = [0u8; 32];
345 }
346 }
347
348 let mut src = data.as_ptr().cast::<u8>();
350 let mut dst = nibbles_slice.as_mut_ptr().add(U256::BYTES);
352 for _ in 0..data.len() {
355 dst = dst.sub(1);
356 *dst = *src;
357 src = src.add(1);
358 }
359
360 cfg_if! {
361 if #[cfg(target_endian = "big")] {
362 let nibbles = U256::from_le_bytes(nibbles_slice);
363 }
364 }
365
366 Self { length, nibbles }
367 }
368
369 #[inline]
385 pub fn pack(&self) -> SmallVec<[u8; 32]> {
386 let packed_len = self.len().div_ceil(2);
387 unsafe { smallvec_with(packed_len, |out| self.pack_to_slice_unchecked(out)) }
388 }
389
390 #[inline]
408 #[track_caller]
409 pub fn pack_to(&self, out: &mut [u8]) {
410 assert!(out.len() >= self.len().div_ceil(2));
411 unsafe { self.pack_to_unchecked(out.as_mut_ptr()) }
413 }
414
415 #[inline]
434 pub unsafe fn pack_to_unchecked(&self, ptr: *mut u8) {
435 let slice = slice::from_raw_parts_mut(ptr.cast(), self.len().div_ceil(2));
436 pack_to_unchecked(self, slice);
437 }
438
439 #[inline]
447 pub unsafe fn pack_to_slice_unchecked(&self, out: &mut [MaybeUninit<u8>]) {
448 pack_to_unchecked(self, out)
449 }
450
451 pub fn to_vec(&self) -> Vec<u8> {
461 self.iter().collect()
462 }
463
464 #[inline]
475 pub const fn iter(&self) -> NibblesIter<'_> {
476 NibblesIter { current: 0, nibbles: self }
477 }
478
479 pub fn get_byte(&self, i: usize) -> Option<u8> {
492 if likely((i < usize::MAX) & self.check_index(i.wrapping_add(1))) {
493 Some(self.get_byte_unchecked(i))
494 } else {
495 None
496 }
497 }
498
499 #[inline]
518 #[track_caller]
519 pub fn get_byte_unchecked(&self, i: usize) -> u8 {
520 self.assert_index(i);
521 if i % 2 == 0 {
522 as_le_slice(&self.nibbles)[U256::BYTES - i / 2 - 1]
523 } else {
524 self.get_unchecked(i) << 4 | self.get_unchecked(i + 1)
525 }
526 }
527
528 #[inline]
530 pub fn increment(&self) -> Option<Self> {
531 if self.is_empty() || self.nibbles == SLICE_MASKS[self.len()] {
532 return None;
533 }
534
535 let mut incremented = *self;
536 let add = INCREMENT_VALUES[self.len()];
537 incremented.nibbles += add;
538 Some(incremented)
539 }
540
541 #[inline]
544 pub fn is_leaf(&self) -> bool {
545 self.last() == Some(16)
546 }
547
548 pub fn starts_with(&self, other: &Self) -> bool {
550 if other.len() > self.len() {
552 return false;
553 }
554
555 if other.is_empty() {
557 return true;
558 }
559
560 let mask = SLICE_MASKS[other.len()];
562 (self.nibbles & mask) == other.nibbles
563 }
564
565 pub fn ends_with(&self, other: &Self) -> bool {
567 if other.is_empty() {
569 return true;
570 }
571
572 if other.len() > self.len() {
574 return false;
575 }
576
577 if self.len() % 2 == other.len() % 2 {
579 return as_le_slice(&self.nibbles)
580 [(NIBBLES - self.len()) / 2..(NIBBLES - self.len() + other.len()) / 2]
581 == as_le_slice(&other.nibbles)[(NIBBLES - other.len()) / 2..];
582 }
583
584 let mut i = 0;
585 while i < other.len() {
586 if self.get_unchecked(self.len() - i - 1) != other.get_unchecked(other.len() - i - 1) {
587 return false;
588 }
589 i += 1;
590 }
591
592 true
593 }
594
595 #[inline]
597 pub fn get(&self, i: usize) -> Option<u8> {
598 if self.check_index(i) {
599 Some(self.get_unchecked(i))
600 } else {
601 None
602 }
603 }
604
605 #[inline]
611 #[track_caller]
612 pub fn get_unchecked(&self, i: usize) -> u8 {
613 self.assert_index(i);
614 let byte = as_le_slice(&self.nibbles)[U256::BYTES - i / 2 - 1];
615 if i % 2 == 0 {
616 byte >> 4
617 } else {
618 byte & 0x0F
619 }
620 }
621
622 #[inline]
628 #[track_caller]
629 pub fn set_at(&mut self, i: usize, value: u8) {
630 assert!(self.check_index(i) && value <= 0xf);
631 unsafe { self.set_at_unchecked(i, value) };
633 }
634
635 #[inline]
641 pub unsafe fn set_at_unchecked(&mut self, i: usize, value: u8) {
642 let byte_index = U256::BYTES - i / 2 - 1;
643
644 cfg_if! {
646 if #[cfg(target_endian = "little")] {
647 let byte = unsafe { &mut self.nibbles.as_le_slice_mut()[byte_index] };
648 } else {
649 let mut le_copy = as_le_slice(&self.nibbles);
653 let byte = &mut le_copy.to_mut()[byte_index];
654 }
655 }
656
657 if i % 2 == 0 {
658 *byte = *byte & 0x0f | value << 4;
659 } else {
660 *byte = *byte & 0xf0 | value;
661 }
662
663 #[cfg(target_endian = "big")]
665 {
666 self.nibbles = U256::from_le_slice(&le_copy);
667 }
668 }
669
670 #[inline]
672 pub fn first(&self) -> Option<u8> {
673 self.get(0)
674 }
675
676 #[inline]
678 pub fn last(&self) -> Option<u8> {
679 let len = self.len();
680 if len == 0 {
681 None
682 } else {
683 Some(self.get_unchecked(len - 1))
684 }
685 }
686
687 pub fn common_prefix_length(&self, other: &Self) -> usize {
698 if self.is_empty() || other.is_empty() {
700 return 0;
701 }
702
703 let min_nibble_len = self.len().min(other.len());
704
705 if min_nibble_len <= 16 {
707 let self_limb = self.nibbles.as_limbs()[3];
709 let other_limb = other.nibbles.as_limbs()[3];
710
711 let mask = u64::MAX << ((16 - min_nibble_len) * 4);
713 let xor = (self_limb ^ other_limb) & mask;
714
715 if xor == 0 {
716 return min_nibble_len;
717 } else {
718 return xor.leading_zeros() as usize / 4;
719 }
720 }
721
722 let xor = if min_nibble_len == NIBBLES && self.len() == other.len() {
723 self.nibbles ^ other.nibbles
725 } else {
726 let mask = SLICE_MASKS[min_nibble_len];
728 (self.nibbles ^ other.nibbles) & mask
729 };
730
731 if xor == U256::ZERO {
732 min_nibble_len
733 } else {
734 xor.leading_zeros() / 4
735 }
736 }
737
738 #[inline]
740 const fn bit_len(&self) -> usize {
741 self.len() * 4
742 }
743
744 #[inline]
746 pub const fn is_empty(&self) -> bool {
747 self.len() == 0
748 }
749
750 #[inline]
752 pub const fn len(&self) -> usize {
753 let len = self.length;
754 debug_assert!(len <= 64);
755 unsafe { core::hint::assert_unchecked(len <= 64) };
756 len
757 }
758
759 #[inline]
764 pub fn as_mut_uint_unchecked(&mut self) -> &mut U256 {
765 &mut self.nibbles
766 }
767
768 #[inline]
776 pub fn slice_unchecked(&self, start: usize, end: usize) -> Self {
777 if end == 0 || end <= start {
779 return Self::new();
780 }
781
782 let slice_to_end = end == self.len();
784 if start == 0 && slice_to_end {
785 return *self;
786 }
787
788 let nibble_len = end - start;
789
790 let nibbles = if start == 0 {
792 self.nibbles & SLICE_MASKS[end]
794 } else {
795 let shifted = self.nibbles << (start * 4);
797 if slice_to_end {
798 shifted
800 } else {
801 shifted & SLICE_MASKS[end - start]
803 }
804 };
805
806 Self { length: nibble_len, nibbles }
807 }
808
809 pub fn slice(&self, range: impl RangeBounds<usize>) -> Self {
815 let start = match range.start_bound() {
817 Bound::Included(&idx) => idx,
818 Bound::Excluded(&idx) => idx + 1,
819 Bound::Unbounded => 0,
820 };
821 let end = match range.end_bound() {
822 Bound::Included(&idx) => idx + 1,
823 Bound::Excluded(&idx) => idx,
824 Bound::Unbounded => self.len(),
825 };
826 assert!(start <= end, "Cannot slice with a start index greater than the end index");
827 assert!(
828 end <= self.len(),
829 "Cannot slice with an end index greater than the length of the nibbles"
830 );
831
832 self.slice_unchecked(start, end)
833 }
834
835 #[inline]
837 pub fn join(&self, other: &Self) -> Self {
838 let mut new = *self;
839 new.extend(other);
840 new
841 }
842
843 #[inline]
849 #[track_caller]
850 pub fn push(&mut self, nibble: u8) {
851 assert!(nibble <= 0xf);
852 self.push_unchecked(nibble);
853 }
854
855 #[inline]
860 pub fn push_unchecked(&mut self, nibble: u8) {
861 let nibble_val = (nibble & 0x0F) as u64;
862 if nibble_val == 0 {
863 self.length += 1;
865 return;
866 }
867
868 let bit_pos = (NIBBLES - self.len() - 1) * 4;
869 let limb_idx = bit_pos / 64;
870 let shift_in_limb = bit_pos % 64;
871
872 unsafe {
874 let limbs = self.nibbles.as_limbs_mut();
875 limbs[limb_idx] |= nibble_val << shift_in_limb;
876 }
877
878 self.length += 1;
879 }
880
881 pub fn pop(&mut self) -> Option<u8> {
883 if self.is_empty() {
884 return None;
885 }
886
887 let shift = (NIBBLES - self.len()) * 4;
889
890 let nibble = (self.nibbles >> shift).as_limbs()[0] as u8 & 0xF;
892
893 let mask_limb_idx = shift / 64;
896 let mask_shift = shift % 64;
897
898 if mask_limb_idx < 4 {
899 unsafe {
901 let limbs = self.nibbles.as_limbs_mut();
902 limbs[mask_limb_idx] &= !(0xF << mask_shift);
903 }
904 }
905
906 self.length -= 1;
907 Some(nibble)
908 }
909
910 pub fn extend(&mut self, other: &Nibbles) {
912 if other.is_empty() {
913 return;
914 }
915
916 self.nibbles |= other.nibbles >> self.bit_len();
917 self.length += other.length;
918 }
919
920 pub fn extend_from_slice(&mut self, other: &[u8]) {
922 assert!(
923 self.length + other.len() * 2 <= NIBBLES,
924 "Cannot extend: resulting length would exceed maximum capacity"
925 );
926 self.extend_from_slice_unchecked(other);
927 }
928
929 pub fn extend_from_slice_unchecked(&mut self, other: &[u8]) {
936 if other.is_empty() {
937 return;
938 }
939
940 let len_bytes = other.len();
941 let mut other = U256::from_be_slice(other);
942 if len_bytes > 0 {
943 other <<= (U256::BYTES - len_bytes) * 8;
944 }
945 self.nibbles |= other >> self.bit_len();
946 self.length += len_bytes * 2;
947 }
948
949 #[inline]
951 pub fn truncate(&mut self, new_len: usize) {
952 assert!(
953 new_len <= self.len(),
954 "Cannot truncate to a length greater than the current length"
955 );
956 *self = self.slice_unchecked(0, new_len);
957 }
958
959 #[inline]
961 pub fn clear(&mut self) {
962 *self = Self::new();
963 }
964
965 #[inline]
967 const fn check_index(&self, i: usize) -> bool {
968 i < self.len()
969 }
970
971 #[inline]
973 fn assert_index(&self, i: usize) {
974 let len = self.len();
975 if i >= len {
976 panic_invalid_index(len, i);
977 }
978 }
979}
980
981#[derive(Debug, Clone)]
995pub struct NibblesIter<'a> {
996 current: usize,
998 nibbles: &'a Nibbles,
1000}
1001
1002impl<'a> Iterator for NibblesIter<'a> {
1003 type Item = u8;
1004
1005 #[inline]
1006 fn next(&mut self) -> Option<Self::Item> {
1007 self.nibbles.get(self.current).inspect(|_| self.current += 1)
1008 }
1009
1010 #[inline]
1011 fn size_hint(&self) -> (usize, Option<usize>) {
1012 let len = self.len();
1013 (len, Some(len))
1014 }
1015}
1016
1017impl<'a> ExactSizeIterator for NibblesIter<'a> {
1018 #[inline]
1019 fn len(&self) -> usize {
1020 self.nibbles.len() - self.current
1021 }
1022}
1023
1024#[inline]
1030unsafe fn pack_to_unchecked(nibbles: &Nibbles, out: &mut [MaybeUninit<u8>]) {
1031 let byte_len = nibbles.len().div_ceil(2);
1032 debug_assert!(out.len() >= byte_len);
1033 let mut src = as_le_slice(&nibbles.nibbles).as_ptr().add(U256::BYTES);
1035 let mut dst = out.as_mut_ptr().cast::<u8>();
1037 for _ in 0..byte_len {
1040 src = src.sub(1);
1041 *dst = *src;
1042 dst = dst.add(1);
1043 }
1044}
1045
1046#[inline]
1054pub unsafe fn smallvec_with<const N: usize>(
1055 len: usize,
1056 f: impl FnOnce(&mut [MaybeUninit<u8>]),
1057) -> SmallVec<[u8; N]> {
1058 let mut buf = smallvec_with_len::<N>(len);
1059 f(unsafe { slice::from_raw_parts_mut(buf.as_mut_ptr().cast(), len) });
1060 buf
1061}
1062
1063#[inline]
1064#[allow(clippy::uninit_vec)]
1065unsafe fn smallvec_with_len<const N: usize>(len: usize) -> SmallVec<[u8; N]> {
1066 if likely(len <= N) {
1067 SmallVec::from_buf_and_len_unchecked(MaybeUninit::<[u8; N]>::uninit(), len)
1068 } else {
1069 let mut vec = Vec::with_capacity(len);
1070 unsafe { vec.set_len(len) };
1071 SmallVec::from_vec(vec)
1072 }
1073}
1074
1075#[inline]
1076#[track_caller]
1077fn check_nibbles(nibbles: &[u8]) {
1078 if !valid_nibbles(nibbles) {
1079 panic_invalid_nibbles();
1080 }
1081}
1082
1083fn valid_nibbles(nibbles: &[u8]) -> bool {
1084 nibbles.iter().all(|&nibble| nibble <= 0xf)
1085}
1086
1087#[cold]
1088#[inline(never)]
1089#[cfg_attr(debug_assertions, track_caller)]
1090const fn panic_invalid_nibbles() -> ! {
1091 panic!("attempted to create invalid nibbles");
1092}
1093
1094#[cold]
1095#[inline(never)]
1096#[cfg_attr(debug_assertions, track_caller)]
1097fn panic_invalid_index(len: usize, i: usize) -> ! {
1098 panic!("index out of bounds: {i} for nibbles of length {len}");
1099}
1100
1101enum ByteContainer<'a, const N: usize> {
1103 #[cfg_attr(target_endian = "big", allow(unused))]
1105 Borrowed(&'a [u8]),
1106 #[cfg_attr(target_endian = "little", allow(unused))]
1108 Owned([u8; N]),
1109}
1110
1111impl<'a, const N: usize> ByteContainer<'a, N> {
1112 #[cfg_attr(target_endian = "little", allow(unused))]
1118 pub(crate) fn to_mut(&mut self) -> &mut [u8; N] {
1119 match self {
1120 ByteContainer::Borrowed(slice) => {
1121 let mut array = [0u8; N];
1122 array[..N].copy_from_slice(&slice[..N]);
1123 *self = ByteContainer::Owned(array);
1124 self.to_mut()
1125 }
1126 ByteContainer::Owned(ref mut array) => array,
1127 }
1128 }
1129}
1130
1131impl<'a, const N: usize> Deref for ByteContainer<'a, N> {
1132 type Target = [u8];
1133
1134 fn deref(&self) -> &Self::Target {
1135 match self {
1136 ByteContainer::Borrowed(slice) => slice,
1137 ByteContainer::Owned(array) => array.as_slice(),
1138 }
1139 }
1140}
1141
1142#[inline]
1144const fn as_le_slice(x: &U256) -> ByteContainer<'_, { U256::BYTES }> {
1145 cfg_if! {
1146 if #[cfg(target_endian = "little")] {
1147 ByteContainer::Borrowed(x.as_le_slice())
1148 } else {
1149 ByteContainer::Owned(x.to_le_bytes())
1150 }
1151 }
1152}
1153
1154#[cfg(test)]
1155mod tests {
1156 use super::*;
1157
1158 #[test]
1159 fn pack() {
1160 let tests = [
1161 (&[][..], &[][..]),
1162 (&[0xa], &[0xa0]),
1163 (&[0xa, 0x0], &[0xa0]),
1164 (&[0xa, 0xb], &[0xab]),
1165 (&[0xa, 0xb, 0x2], &[0xab, 0x20]),
1166 (&[0xa, 0xb, 0x2, 0x0], &[0xab, 0x20]),
1167 (&[0xa, 0xb, 0x2, 0x7], &[0xab, 0x27]),
1168 ];
1169 for (input, expected) in tests {
1170 assert!(valid_nibbles(input));
1171 let nibbles = Nibbles::from_nibbles(input);
1172 let encoded = nibbles.pack();
1173 assert_eq!(
1174 &encoded[..],
1175 expected,
1176 "input: {input:x?}, expected: {expected:x?}, got: {encoded:x?}",
1177 );
1178 }
1179 }
1180
1181 #[test]
1182 fn get_unchecked() {
1183 for len in 0..NIBBLES {
1184 let raw = (0..16).cycle().take(len).collect::<Vec<u8>>();
1185 let nibbles = Nibbles::from_nibbles(&raw);
1186 for (i, raw_nibble) in raw.into_iter().enumerate() {
1187 assert_eq!(nibbles.get_unchecked(i), raw_nibble);
1188 }
1189 }
1190 }
1191
1192 #[test]
1193 fn set_at_unchecked() {
1194 for len in 0..=NIBBLES {
1195 let raw = (0..16).cycle().take(len).collect::<Vec<u8>>();
1196 let mut nibbles = Nibbles::from_nibbles(&raw);
1197 for (i, raw_nibble) in raw.iter().enumerate() {
1198 let new_nibble = (raw_nibble + 1) % 16;
1199 unsafe { nibbles.set_at_unchecked(i, new_nibble) };
1200
1201 let mut new_raw_nibbles = nibbles.clone().to_vec();
1202 new_raw_nibbles[i] = new_nibble;
1203 let new_nibbles = Nibbles::from_nibbles(&new_raw_nibbles);
1204 assert_eq!(nibbles, new_nibbles,);
1205 }
1206 }
1207 }
1208
1209 #[test]
1210 fn push_pop() {
1211 let mut nibbles = Nibbles::new();
1212 nibbles.push(0x0A);
1213 assert_eq!(nibbles.get_unchecked(0), 0x0A);
1214 assert_eq!(nibbles.len(), 1);
1215
1216 assert_eq!(nibbles.pop(), Some(0x0A));
1217 assert_eq!(nibbles.len(), 0);
1218 }
1219
1220 #[test]
1221 fn get_byte() {
1222 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1223 assert_eq!(nibbles.get_byte(0), Some(0xAB));
1224 assert_eq!(nibbles.get_byte(1), Some(0xBC));
1225 assert_eq!(nibbles.get_byte(2), Some(0xCD));
1226 assert_eq!(nibbles.get_byte(3), None);
1227 assert_eq!(nibbles.get_byte(usize::MAX), None);
1228 }
1229
1230 #[test]
1231 fn get_byte_unchecked() {
1232 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1233 assert_eq!(nibbles.get_byte_unchecked(0), 0xAB);
1234 assert_eq!(nibbles.get_byte_unchecked(1), 0xBC);
1235 assert_eq!(nibbles.get_byte_unchecked(2), 0xCD);
1236 }
1237
1238 #[test]
1239 fn clone() {
1240 let a = Nibbles::from_nibbles([1, 2, 3]);
1241 #[allow(clippy::redundant_clone)]
1242 let b = a;
1243 assert_eq!(a, b);
1244 }
1245
1246 #[test]
1247 fn ord() {
1248 let nibbles1 = Nibbles::default();
1250 let nibbles2 = Nibbles::default();
1251 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Equal);
1252
1253 let nibbles1 = Nibbles::default();
1255 let nibbles2 = Nibbles::from_nibbles([0]);
1256 assert_eq!(nibbles2.cmp(&nibbles1), Ordering::Greater);
1257
1258 let nibbles1 = Nibbles::unpack([0x12, 0x34]);
1260 let nibbles2 = Nibbles::unpack([0x12, 0x34]);
1261 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Equal);
1262
1263 let short = Nibbles::unpack([0x12]);
1265 let long = Nibbles::unpack([0x12, 0x34]);
1266 assert_eq!(short.cmp(&long), Ordering::Less);
1267
1268 let nibbles1 = Nibbles::unpack([0x12, 0x34]);
1270 let nibbles2 = Nibbles::unpack([0x12, 0x35]);
1271 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1272
1273 let nibbles1 = Nibbles::unpack([0x12, 0x34]);
1275 let nibbles2 = Nibbles::unpack([0x13, 0x34]);
1276 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1277
1278 let nibbles1 = Nibbles::unpack([0x1]);
1280 let nibbles2 = Nibbles::unpack([0x2]);
1281 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1282
1283 let odd = Nibbles::unpack([0x1]);
1285 let even = Nibbles::unpack([0x12]);
1286 assert_eq!(odd.cmp(&even), Ordering::Less);
1287
1288 let nibbles1 = Nibbles::unpack([0x12, 0x34, 0x56, 0x78]);
1290 let nibbles2 = Nibbles::unpack([0x12, 0x34, 0x56, 0x79]);
1291 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1292
1293 let nibbles1 = Nibbles::from_nibbles([0x0, 0x0]);
1294 let nibbles2 = Nibbles::from_nibbles([0x1]);
1295 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1296
1297 let nibbles1 = Nibbles::from_nibbles([0x1]);
1298 let nibbles2 = Nibbles::from_nibbles([0x0, 0x2]);
1299 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Greater);
1300
1301 let nibbles1 = Nibbles::from_nibbles([vec![0; 61], vec![1; 1], vec![0; 1]].concat());
1302 let nibbles2 = Nibbles::from_nibbles([vec![0; 61], vec![1; 1], vec![0; 2]].concat());
1303 assert_eq!(nibbles1.cmp(&nibbles2), Ordering::Less);
1304 }
1305
1306 #[test]
1307 fn starts_with() {
1308 let nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1309
1310 let empty = Nibbles::default();
1312 assert!(nibbles.starts_with(&empty));
1313 assert!(empty.starts_with(&empty));
1314 assert!(!empty.starts_with(&nibbles));
1315
1316 assert!(nibbles.starts_with(&nibbles));
1318
1319 let prefix = Nibbles::from_nibbles([1, 2]);
1321 assert!(nibbles.starts_with(&prefix));
1322 assert!(!prefix.starts_with(&nibbles));
1323
1324 let different = Nibbles::from_nibbles([2, 2, 3, 4]);
1326 assert!(!nibbles.starts_with(&different));
1327
1328 let longer = Nibbles::from_nibbles([1, 2, 3, 4, 5, 6]);
1330 assert!(!nibbles.starts_with(&longer));
1331
1332 let even_nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1334 let odd_prefix = Nibbles::from_nibbles([1, 2, 3]);
1335 assert!(even_nibbles.starts_with(&odd_prefix));
1336
1337 let odd_nibbles = Nibbles::from_nibbles([1, 2, 3]);
1339 let even_prefix = Nibbles::from_nibbles([1, 2]);
1340 assert!(odd_nibbles.starts_with(&even_prefix));
1341 }
1342
1343 #[test]
1344 fn ends_with() {
1345 let nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1346
1347 let empty = Nibbles::default();
1349 assert!(nibbles.ends_with(&empty));
1350 assert!(empty.ends_with(&empty));
1351 assert!(!empty.ends_with(&nibbles));
1352
1353 assert!(nibbles.ends_with(&nibbles));
1355
1356 let suffix = Nibbles::from_nibbles([3, 4]);
1358 assert!(nibbles.ends_with(&suffix));
1359 assert!(!suffix.ends_with(&nibbles));
1360
1361 let different = Nibbles::from_nibbles([2, 3, 5]);
1363 assert!(!nibbles.ends_with(&different));
1364
1365 let longer = Nibbles::from_nibbles([2, 3, 4, 5, 6]);
1367 assert!(!nibbles.ends_with(&longer));
1368
1369 let even_nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1371 let odd_suffix = Nibbles::from_nibbles([2, 3, 4]);
1372 assert!(even_nibbles.ends_with(&odd_suffix));
1373
1374 let odd_nibbles = Nibbles::from_nibbles([1, 2, 3]);
1376 let even_suffix = Nibbles::from_nibbles([2, 3]);
1377 assert!(odd_nibbles.ends_with(&even_suffix));
1378 }
1379
1380 #[test]
1381 fn slice() {
1382 let empty = Nibbles::default();
1384 assert_eq!(empty.slice(..), empty);
1385
1386 let even = Nibbles::from_nibbles([0, 1, 2, 3, 4, 5]);
1388
1389 assert_eq!(even.slice(..), even);
1391 assert_eq!(even.slice(0..6), even);
1392
1393 assert_eq!(even.slice(3..3), Nibbles::default());
1395
1396 assert_eq!(even.slice(0..2), Nibbles::from_iter(0..2));
1398
1399 assert_eq!(even.slice(2..4), Nibbles::from_iter(2..4));
1401
1402 assert_eq!(even.slice(4..6), Nibbles::from_iter(4..6));
1404
1405 let odd = Nibbles::from_iter(0..5);
1407
1408 assert_eq!(odd.slice(..), odd);
1410 assert_eq!(odd.slice(0..5), odd);
1411
1412 assert_eq!(odd.slice(0..3), Nibbles::from_iter(0..3));
1414
1415 assert_eq!(odd.slice(1..4), Nibbles::from_iter(1..4));
1417
1418 assert_eq!(odd.slice(1..3), Nibbles::from_iter(1..3));
1420
1421 assert_eq!(odd.slice(2..5), Nibbles::from_iter(2..5));
1423
1424 assert_eq!(odd.slice(1..4), Nibbles::from_iter(1..4));
1426
1427 assert_eq!(even.slice(2..3), Nibbles::from_iter(2..3));
1429
1430 assert_eq!(even.slice(3..4), Nibbles::from_iter(3..4));
1431
1432 assert_eq!(even.slice(2..), Nibbles::from_iter(2..6));
1434 assert_eq!(even.slice(..4), Nibbles::from_iter(0..4));
1435 assert_eq!(even.slice(..=3), Nibbles::from_iter(0..4));
1436
1437 assert_eq!(
1439 Nibbles::from_iter((0..16).cycle().take(64)).slice(1..),
1440 Nibbles::from_iter((0..16).cycle().take(64).skip(1))
1441 );
1442 }
1443
1444 #[test]
1445 fn common_prefix_length() {
1446 let empty = Nibbles::default();
1448 assert_eq!(empty.common_prefix_length(&empty), 0);
1449
1450 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1452 let nibbles2 = Nibbles::from_nibbles([1, 2, 3, 4]);
1453 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 4);
1454 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 4);
1455
1456 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1458 let nibbles2 = Nibbles::from_nibbles([1, 2, 5, 6]);
1459 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 2);
1460 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 2);
1461
1462 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1464 let nibbles2 = Nibbles::from_nibbles([1, 2, 3, 7]);
1465 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 3);
1466 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 3);
1467
1468 let nibbles1 = Nibbles::from_nibbles([5, 6, 7, 8]);
1470 let nibbles2 = Nibbles::from_nibbles([1, 2, 3, 4]);
1471 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 0);
1472 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 0);
1473
1474 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4, 5, 6]);
1476 let nibbles2 = Nibbles::from_nibbles([1, 2, 3]);
1477 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 3);
1478 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 3);
1479
1480 let nibbles1 = Nibbles::from_nibbles([1, 2, 3]);
1482 let nibbles2 = Nibbles::from_nibbles([1, 2, 7]);
1483 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 2);
1484 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 2);
1485
1486 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1488 let nibbles2 = Nibbles::from_nibbles([5, 2, 3, 4]);
1489 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 0);
1490 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 0);
1491
1492 let nibbles1 = Nibbles::from_nibbles([1, 2, 3, 4]);
1494 assert_eq!(nibbles1.common_prefix_length(&empty), 0);
1495 assert_eq!(empty.common_prefix_length(&nibbles1), 0);
1496
1497 let nibbles1 =
1499 Nibbles::from_nibbles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]);
1500 let nibbles2 =
1501 Nibbles::from_nibbles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1]);
1502 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 15);
1503 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 15);
1504
1505 let nibbles1 =
1507 Nibbles::from_nibbles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0]);
1508 let nibbles2 = Nibbles::from_nibbles([
1509 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,
1510 11, 12, 13, 14, 15, 0,
1511 ]);
1512 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 16);
1513 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 16);
1514
1515 let nibbles1 = Nibbles::from_nibbles([
1517 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,
1518 11, 12, 13, 14, 15, 0,
1519 ]);
1520 let nibbles2 = Nibbles::from_nibbles([
1521 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,
1522 11, 12, 13, 14, 15, 1,
1523 ]);
1524 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 31);
1525 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 31);
1526
1527 let nibbles1 = Nibbles::from_nibbles([
1529 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,
1530 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
1531 ]);
1532 let nibbles2 = Nibbles::from_nibbles([
1533 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,
1534 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1,
1535 ]);
1536 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 47);
1537 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 47);
1538
1539 let nibbles1 = Nibbles::from_nibbles([
1541 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,
1542 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,
1543 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0,
1544 ]);
1545 let nibbles2 = Nibbles::from_nibbles([
1546 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,
1547 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,
1548 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1,
1549 ]);
1550 assert_eq!(nibbles1.common_prefix_length(&nibbles2), 63);
1551 assert_eq!(nibbles2.common_prefix_length(&nibbles1), 63);
1552
1553 let current = Nibbles::from_nibbles([0u8; 64]);
1554 let path = Nibbles::from_nibbles([vec![0u8; 63], vec![2u8]].concat());
1555 assert_eq!(current.common_prefix_length(&path), 63);
1556
1557 let current = Nibbles::from_nibbles([0u8; 63]);
1558 let path = Nibbles::from_nibbles([vec![0u8; 62], vec![1u8], vec![0u8]].concat());
1559 assert_eq!(current.common_prefix_length(&path), 62);
1560 }
1561
1562 #[test]
1563 fn truncate() {
1564 let mut nibbles = Nibbles::default();
1566 nibbles.truncate(0);
1567 assert_eq!(nibbles, Nibbles::default());
1568
1569 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1571 nibbles.truncate(0);
1572 assert_eq!(nibbles, Nibbles::default());
1573
1574 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1576 nibbles.truncate(4);
1577 assert_eq!(nibbles, Nibbles::from_nibbles([1, 2, 3, 4]));
1578
1579 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1581 nibbles.truncate(2);
1582 assert_eq!(nibbles, Nibbles::from_nibbles([1, 2]));
1583
1584 let mut nibbles = Nibbles::from_nibbles([1, 2, 3, 4]);
1586 nibbles.truncate(2);
1587 assert_eq!(nibbles, Nibbles::from_nibbles([1, 2]));
1588
1589 let mut nibbles = Nibbles::from_nibbles([5, 6, 7, 8]);
1591 nibbles.truncate(1);
1592 assert_eq!(nibbles, Nibbles::from_nibbles([5]));
1593 }
1594
1595 #[test]
1596 fn push_unchecked() {
1597 let mut nibbles = Nibbles::default();
1599 nibbles.push_unchecked(0x5);
1600 assert_eq!(nibbles, Nibbles::from_nibbles([0x5]));
1601
1602 nibbles.push_unchecked(0xA);
1604 assert_eq!(nibbles, Nibbles::from_nibbles([0x5, 0xA]));
1605
1606 let mut nibbles = Nibbles::default();
1608 for nibble in [0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8] {
1609 nibbles.push_unchecked(nibble);
1610 }
1611 assert_eq!(nibbles, Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]));
1612
1613 let mut nibbles = Nibbles::default();
1615 nibbles.push_unchecked(0xFF); nibbles.push_unchecked(0x1A); nibbles.push_unchecked(0x25); assert_eq!(nibbles, Nibbles::from_nibbles([0xF, 0xA, 0x5]));
1619
1620 let mut nibbles = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
1622 nibbles.push_unchecked(0x4);
1623 assert_eq!(nibbles, Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]));
1624
1625 let mut nibbles = Nibbles::default();
1627 nibbles.push_unchecked(0x0);
1628 nibbles.push_unchecked(0xF);
1629 assert_eq!(nibbles, Nibbles::from_nibbles([0x0, 0xF]));
1630
1631 let mut nibbles = Nibbles::default();
1633 let test_sequence: Vec<u8> = (0..32).map(|i| i % 16).collect();
1634 for &nibble in &test_sequence {
1635 nibbles.push_unchecked(nibble);
1636 }
1637 assert_eq!(nibbles, Nibbles::from_nibbles(test_sequence));
1638 }
1639
1640 #[test]
1641 fn unpack() {
1642 for (test_idx, bytes) in (0..=32).map(|i| vec![0xFF; i]).enumerate() {
1643 let packed_nibbles = Nibbles::unpack(&bytes);
1644 let nibbles = Nibbles::unpack(&bytes);
1645
1646 assert_eq!(
1647 packed_nibbles.len(),
1648 nibbles.len(),
1649 "Test case {test_idx}: Length mismatch for bytes {bytes:?}",
1650 );
1651 assert_eq!(
1652 packed_nibbles.len(),
1653 bytes.len() * 2,
1654 "Test case {test_idx}: Expected length to be 2x byte length",
1655 );
1656
1657 for i in 0..packed_nibbles.len() {
1659 assert_eq!(
1660 packed_nibbles.get_unchecked(i),
1661 nibbles.get_unchecked(i),
1662 "Test case {}: Nibble at index {} differs for bytes {:?}: Nibbles={:?}, Nibbles={:?}",
1663 test_idx,
1664 i,
1665 bytes,
1666 packed_nibbles.get_unchecked(i),
1667 nibbles.get_unchecked(i)
1668 );
1669 }
1670 }
1671
1672 let nibbles = Nibbles::unpack([0xAB, 0xCD]);
1673 assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);
1674 }
1675
1676 #[test]
1677 fn increment() {
1678 assert_eq!(
1680 Nibbles::from_nibbles([0x0, 0x0, 0x0]).increment().unwrap(),
1681 Nibbles::from_nibbles([0x0, 0x0, 0x1])
1682 );
1683
1684 assert_eq!(
1686 Nibbles::from_nibbles([0x0, 0x0, 0xF]).increment().unwrap(),
1687 Nibbles::from_nibbles([0x0, 0x1, 0x0])
1688 );
1689
1690 assert_eq!(
1692 Nibbles::from_nibbles([0x0, 0xF, 0xF]).increment().unwrap(),
1693 Nibbles::from_nibbles([0x1, 0x0, 0x0])
1694 );
1695
1696 assert_eq!(
1698 Nibbles::from_nibbles([0xE, 0xF, 0xF]).increment().unwrap(),
1699 Nibbles::from_nibbles([0xF, 0x0, 0x0])
1700 );
1701
1702 assert_eq!(Nibbles::from_nibbles([0xF, 0xF, 0xF]).increment(), None);
1704
1705 assert_eq!(Nibbles::new().increment(), None);
1707
1708 assert_eq!(Nibbles::from_nibbles([0x5]).increment().unwrap(), Nibbles::from_nibbles([0x6]));
1710
1711 assert_eq!(Nibbles::from_nibbles([0xF]).increment(), None);
1713
1714 assert_eq!(
1716 Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x5]).increment().unwrap(),
1717 Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x6])
1718 );
1719
1720 assert_eq!(
1722 Nibbles::from_nibbles([0x1, 0x2, 0x3, 0xF, 0xF]).increment().unwrap(),
1723 Nibbles::from_nibbles([0x1, 0x2, 0x4, 0x0, 0x0])
1724 );
1725 }
1726
1727 #[test]
1728 fn iter() {
1729 let empty = Nibbles::new();
1731 assert_eq!(empty.iter().collect::<Vec<_>>(), vec![]);
1732
1733 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1735 let collected: Vec<u8> = nibbles.iter().collect();
1736 assert_eq!(collected, vec![0x0A, 0x0B, 0x0C, 0x0D]);
1737
1738 assert_eq!(nibbles.iter().collect::<Vec<_>>(), nibbles.to_vec());
1740
1741 let single = Nibbles::from_nibbles([0x05]);
1743 assert_eq!(single.iter().collect::<Vec<_>>(), vec![0x05]);
1744
1745 let odd = Nibbles::from_nibbles([0x01, 0x02, 0x03]);
1747 assert_eq!(odd.iter().collect::<Vec<_>>(), vec![0x01, 0x02, 0x03]);
1748
1749 let max_nibbles: Vec<u8> = (0..64).map(|i| (i % 16) as u8).collect();
1751 let max = Nibbles::from_nibbles(&max_nibbles);
1752 assert_eq!(max.iter().collect::<Vec<_>>(), max_nibbles);
1753
1754 let nibbles = Nibbles::from_nibbles([0x0A, 0x0B, 0x0C, 0x0D]);
1756 let mut iter = nibbles.iter();
1757 assert_eq!(iter.len(), 4);
1758 assert_eq!(iter.size_hint(), (4, Some(4)));
1759
1760 iter.next();
1761 assert_eq!(iter.len(), 3);
1762 assert_eq!(iter.size_hint(), (3, Some(3)));
1763
1764 iter.next();
1765 iter.next();
1766 assert_eq!(iter.len(), 1);
1767 assert_eq!(iter.size_hint(), (1, Some(1)));
1768
1769 iter.next();
1770 assert_eq!(iter.len(), 0);
1771 assert_eq!(iter.size_hint(), (0, Some(0)));
1772 assert_eq!(iter.next(), None);
1773
1774 let nibbles = Nibbles::from_nibbles([0x01, 0x02, 0x03, 0x04]);
1776 let mut iter1 = nibbles.iter();
1777 iter1.next();
1778 let iter2 = iter1.clone();
1779
1780 assert_eq!(iter1.collect::<Vec<_>>(), vec![0x02, 0x03, 0x04]);
1781 assert_eq!(iter2.collect::<Vec<_>>(), vec![0x02, 0x03, 0x04]);
1782 }
1783
1784 #[cfg(feature = "arbitrary")]
1785 mod arbitrary {
1786 use super::*;
1787 use proptest::{collection::vec, prelude::*};
1788
1789 proptest::proptest! {
1790 #[test]
1791 #[cfg_attr(miri, ignore = "no proptest")]
1792 fn pack_unpack_roundtrip(input in vec(any::<u8>(), 0..32)) {
1793 let nibbles = Nibbles::unpack(&input);
1794 prop_assert!(valid_nibbles(&nibbles.to_vec()));
1795 let packed = nibbles.pack();
1796 prop_assert_eq!(&packed[..], input);
1797 }
1798 }
1799 }
1800}