#nibble #packed #bit

halfling

A collection of basic utilities for working with nibbles

11 unstable releases (3 breaking)

new 0.4.1 May 11, 2024
0.4.0 May 11, 2024
0.3.0 Apr 21, 2024
0.2.1 Feb 4, 2024
0.1.4 Dec 28, 2023

#592 in Encoding

Download history 2/week @ 2024-02-14 9/week @ 2024-02-21 5/week @ 2024-02-28 1/week @ 2024-03-13 17/week @ 2024-03-27 33/week @ 2024-04-03 151/week @ 2024-04-17 16/week @ 2024-04-24 1/week @ 2024-05-01 230/week @ 2024-05-08

398 downloads per month
Used in quadboard

MIT license

22KB
431 lines

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 Nibble with 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>>());

// currently, it seems like rustc can't apply the same optimisation to non-unit enum variants
assert_eq!(std::mem::size_of<Result<Nibble, Nibble>>(), 2)

Dependencies

~325–790KB
~19K SLoC