Skip to content

A set of basic utilities for handling nibbles in Rust.

License

Notifications You must be signed in to change notification settings

eikopf/halfling

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

72 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Halfling

A library of basic utilities for working with nibbles.

Usage

The core type in halfling is Nibble, which is effectively a wrapper around a u8 that guarantees it will always be strictly less than 16.

// nibbles can be constructed safely with Nibble::new
let valid_nibble = Nibble::new(10);     // returns Some(10)
let invalid_nibble = Nibble::new(16);   // returns None

// if you already know a value to be less than 16, you can use Nibble::new_unchecked
let quick_nibble = unsafe { Nibble::new_unchecked(6) };
// using Nibble::new_unchecked with a value greater than 16 is undefined behaviour

Because the smallest unit of memory in Rust is a byte, it isn't possible to construct a Nibble without consuming the redundant upper bits. However, it's possible to use some enum trickery to tell the compiler which u8 values are valid Nibble values, and so the other 240 values are available as niches.

// a Nibble is a byte-width struct
assert_eq!(std::mem::size_of<Nibble>(), 1);

// because Nibble has well-defined niches, Option<Nibble> is also byte-width
assert_eq!(std::mem::size_of<Nibble>(), std::mem::size_of<Option<Nibble>>());

This crate also provides the Nibbles type, which is an iterator that wraps a &[u8] and yields its nibbles sequentially. Since the ordering of nibbles within bytes is a matter of interpretation (it is a kind of endianness), the Ordering trait is provided to explicitly control how bytes are interpreted; it is implemented by the Le and Be marker structs.

let bytes = vec![0xE2, 0x17, 0xDC];

// nibbles in little-endian order
let le = Nibbles::new_le(&bytes).collect::<Vec<_>>();
// nibbles in big-endian order
let be = Nibbles::new_le(&bytes).collect::<Vec<_>>();

assert!(le[0].get(), 0x2);
assert!(le[1].get(), 0xE);
assert!(le[2].get(), 0x7);
assert!(le[3].get(), 0x1);
assert!(le[4].get(), 0xC);
assert!(le[5].get(), 0xD);

assert!(be[0].get(), 0xE);
assert!(be[1].get(), 0x2);
assert!(be[2].get(), 0x1);
assert!(be[3].get(), 0x7);
assert!(be[4].get(), 0xD);
assert!(be[5].get(), 0xC);

About

A set of basic utilities for handling nibbles in Rust.

Resources

License

Stars

Watchers

Forks

Languages