Struct Nibbles

Source
#[repr(C)]
pub struct Nibbles { /* private fields */ }
Expand description

Structure representing a sequence of nibbles.

A nibble is a 4-bit value, and this structure is used to store the nibble sequence representing the keys in a Merkle Patricia Trie (MPT). Using nibbles simplifies trie operations and enables consistent key representation in the MPT.

§Internal representation

The internal representation is currently a U256 that stores two nibbles per byte. Nibbles are stored inline (on the stack), and can be up to a length of 64 nibbles, or 32 unpacked bytes.

Additionally, a separate length field is stored to track the actual length of the nibble sequence. When the U256 is modified directly, the length field must be updated accordingly. Otherwise, the behavior is undefined.

Nibbles are stored with most significant bits set first, meaning that a nibble sequence 0x101 will be stored as 0x101...0, and not 0x0...101.

§Examples

use nybbles::Nibbles;

let bytes = [0xAB, 0xCD];
let nibbles = Nibbles::unpack(&bytes);
assert_eq!(nibbles, Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]));
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);

let packed = nibbles.pack();
assert_eq!(&packed[..], &bytes[..]);

Implementations§

Source§

impl Nibbles

Source

pub const fn new() -> Self

Creates a new empty Nibbles instance.

§Examples
let nibbles = Nibbles::new();
assert_eq!(nibbles.len(), 0);
Source

pub fn from_iter_unchecked<I>(iter: I) -> Self
where I: IntoIterator<Item = u8>,

Creates a new Nibbles instance from the given iterator over nibbles, without checking their validity.

Note that only the low nibble of every byte will be stored as a nibble, i.e. for 0x12 we will store a nibble 2.

For checked version, use the FromIterator implementation.

§Examples
let nibbles = Nibbles::from_iter_unchecked([0x0A, 0x0B, 0x0C, 0x0D]);
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);
Source

pub fn from_nibbles<T: AsRef<[u8]>>(nibbles: T) -> Self

Creates a new Nibbles instance from the given nibbles.

§Panics

Panics if the any of the bytes is not a valid nibble (0..=0x0f).

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]);
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);

Invalid values will cause panics:

let nibbles = Nibbles::from_nibbles(&[0xFF]);
Source

pub fn from_nibbles_unchecked<T: AsRef<[u8]>>(nibbles: T) -> Self

Creates a new Nibbles instance from the given nibbles.

Note that only the low nibble of every byte will be stored as a nibble, i.e. for 0x12 we will store a nibble 2.

For checked version, use Nibbles::from_nibbles.

§Examples
let nibbles = Nibbles::from_nibbles_unchecked(&[0x0A, 0x0B, 0x0C, 0x0D]);
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);

Invalid values will not cause panics:

let nibbles = Nibbles::from_nibbles_unchecked(&[0xFF]);
assert_eq!(nibbles.to_vec(), vec![0x0F]);
Source

pub fn unpack(data: impl AsRef<[u8]>) -> Self

Converts a byte slice into a Nibbles instance containing the nibbles (half-bytes or 4 bits) that make up the input byte data.

§Panics

Panics if the length of the input is greater than 32 bytes.

§Examples
let nibbles = Nibbles::unpack(&[0xAB, 0xCD]);
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);
let nibbles = Nibbles::unpack(&[0xAB; 33]);
Source

pub unsafe fn unpack_unchecked(data: &[u8]) -> Self

Converts a byte slice into a Nibbles instance containing the nibbles (half-bytes or 4 bits) that make up the input byte data.

§Safety

The caller must ensure that the length of the input is less than or equal to the size of U256, which is 32 bytes.

§Examples
// SAFETY: the length of the input is less than 32 bytes.
let nibbles = unsafe { Nibbles::unpack_unchecked(&[0xAB, 0xCD]) };
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);
Source

pub fn pack(&self) -> SmallVec<[u8; 32]>

Packs the nibbles into the given slice.

This method combines each pair of consecutive nibbles into a single byte, effectively reducing the size of the data by a factor of two.

If the number of nibbles is odd, the last nibble is shifted left by 4 bits and added to the packed byte vector.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C]);
assert_eq!(nibbles.pack()[..], [0xAB, 0xC0]);
Source

pub fn pack_to(&self, out: &mut [u8])

Packs the nibbles into the given slice.

See pack for more information.

§Panics

Panics if the slice is not at least (self.len() + 1) / 2 bytes long.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C]);
let mut packed = [0; 2];
nibbles.pack_to(&mut packed);
assert_eq!(packed[..], [0xAB, 0xC0]);
Source

pub unsafe fn pack_to_unchecked(&self, ptr: *mut u8)

Packs the nibbles into the given pointer.

See pack for more information.

§Safety

ptr must be valid for at least (self.len() + 1) / 2 bytes.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]);
let mut packed = [0; 2];
// SAFETY: enough capacity.
unsafe { nibbles.pack_to_unchecked(packed.as_mut_ptr()) };
assert_eq!(packed[..], [0xAB, 0xCD]);
Source

pub unsafe fn pack_to_slice_unchecked(&self, out: &mut [MaybeUninit<u8>])

Packs the nibbles into the given slice without checking its length.

See pack for more information.

§Safety

out must be valid for at least (self.len() + 1) / 2 bytes.

Source

pub fn to_vec(&self) -> Vec<u8>

Converts the nibbles into a vector of nibbles.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]);
assert_eq!(nibbles.to_vec(), vec![0x0A, 0x0B, 0x0C, 0x0D]);
Source

pub const fn iter(&self) -> NibblesIter<'_>

Returns an iterator over the nibbles.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]);
let collected: Vec<u8> = nibbles.iter().collect();
assert_eq!(collected, vec![0x0A, 0x0B, 0x0C, 0x0D]);
Source

pub fn get_byte(&self, i: usize) -> Option<u8>

Gets the byte at the given index by combining two consecutive nibbles.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]);
assert_eq!(nibbles.get_byte(0), Some(0xAB));
assert_eq!(nibbles.get_byte(1), Some(0xBC));
assert_eq!(nibbles.get_byte(2), Some(0xCD));
assert_eq!(nibbles.get_byte(3), None);
Source

pub fn get_byte_unchecked(&self, i: usize) -> u8

Gets the byte at the given index by combining two consecutive nibbles.

§Panics

Panics if i..i + 1 is out of bounds.

§Examples
let nibbles = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D]);
// SAFETY: in range.
unsafe {
    assert_eq!(nibbles.get_byte_unchecked(0), 0xAB);
    assert_eq!(nibbles.get_byte_unchecked(1), 0xBC);
    assert_eq!(nibbles.get_byte_unchecked(2), 0xCD);
}
Source

pub fn increment(&self) -> Option<Self>

Increments the nibble sequence by one.

Source

pub fn is_leaf(&self) -> bool

The last element of the hex vector is used to determine whether the nibble sequence represents a leaf or an extension node. If the last element is 0x10 (16), then it’s a leaf.

Source

pub fn starts_with(&self, other: &Self) -> bool

Returns true if this nibble sequence starts with the given prefix.

Source

pub fn ends_with(&self, other: &Self) -> bool

Returns true if this nibble sequence ends with the given suffix.

Source

pub fn get(&self, i: usize) -> Option<u8>

Returns the nibble at the given index.

Source

pub fn get_unchecked(&self, i: usize) -> u8

Returns the nibble at the given index.

§Panics

Panics if the index is out of bounds.

Source

pub fn set_at(&mut self, i: usize, value: u8)

Sets the nibble at the given index.

§Panics

Panics if the index is out of bounds, or if value is not a valid nibble (0..=0x0f).

Source

pub unsafe fn set_at_unchecked(&mut self, i: usize, value: u8)

Sets the nibble at the given index, without checking its validity.

§Safety

The caller must ensure that the index is within bounds.

Source

pub fn first(&self) -> Option<u8>

Returns the first nibble of this nibble sequence.

Source

pub fn last(&self) -> Option<u8>

Returns the last nibble of this nibble sequence.

Source

pub fn common_prefix_length(&self, other: &Self) -> usize

Returns the length of the common prefix between this nibble sequence and the given.

§Examples
let a = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]);
let b = Nibbles::from_nibbles(&[0x0A, 0x0B, 0x0C, 0x0E]);
assert_eq!(a.common_prefix_length(&b), 3);
Source

pub const fn is_empty(&self) -> bool

Returns true if this Nibbles is empty.

Source

pub const fn len(&self) -> usize

Returns the total number of nibbles in this Nibbles.

Source

pub fn as_mut_uint_unchecked(&mut self) -> &mut U256

Returns a mutable reference to the underlying U256.

Note that it is possible to create invalid Nibbles instances using this method. See the type docs for more details.

Source

pub fn slice_unchecked(&self, start: usize, end: usize) -> Self

Creates new nibbles containing the nibbles in the specified range [start, end) without checking bounds.

§Safety

This method does not verify that the provided range is valid for this nibble sequence. The caller must ensure that start <= end and end <= self.len().

Source

pub fn slice(&self, range: impl RangeBounds<usize>) -> Self

Creates new nibbles containing the nibbles in the specified range.

§Panics

This method will panic if the range is out of bounds for this nibble sequence.

Source

pub fn join(&self, other: &Self) -> Self

Join two nibble sequences together.

Source

pub fn push(&mut self, nibble: u8)

Pushes a nibble to the end of the current nibbles.

§Panics

Panics if the nibble is not a valid nibble (0..=0x0f).

Source

pub fn push_unchecked(&mut self, nibble: u8)

Pushes a nibble to the end of the current nibbles without checking its validity.

Note that only the low nibble of the byte is used. For example, for byte 0x12, only the nibble 0x2 is pushed.

Source

pub fn pop(&mut self) -> Option<u8>

Pops a nibble from the end of the current nibbles.

Source

pub fn extend(&mut self, other: &Nibbles)

Extend the current nibbles with another nibbles.

Source

pub fn extend_from_slice(&mut self, other: &[u8])

Extend the current nibbles with another byte slice.

Source

pub fn extend_from_slice_unchecked(&mut self, other: &[u8])

Extend the current nibbles with another byte slice.

§Caution

This method does not check if the resulting length would exceed the maximum capacity of Nibbles.

Source

pub fn truncate(&mut self, new_len: usize)

Truncates the current nibbles to the given length.

Source

pub fn clear(&mut self)

Clears the current nibbles.

Trait Implementations§

Source§

impl Clone for Nibbles

Source§

fn clone(&self) -> Nibbles

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Nibbles

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Nibbles

Source§

fn default() -> Nibbles

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for Nibbles

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl FromIterator<u8> for Nibbles

Source§

fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self

Creates a value from an iterator. Read more
Source§

impl Hash for Nibbles

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for Nibbles

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq for Nibbles

Source§

fn eq(&self, other: &Nibbles) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd for Nibbles

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Serialize for Nibbles

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Copy for Nibbles

Source§

impl Eq for Nibbles

Source§

impl StructuralPartialEq for Nibbles

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,