dusk-bytes
dusk-bytes is a small, no_std friendly crate that helps you implement
fixed-size (de)serialization for your types using const generics.
A type that can be represented by exactly N bytes implements [Serializable<N>]. From there, the crate provides convenience traits to:
- deserialize from slices and byte readers (
DeserializableSlice). - parse hex strings (
ParseHexStr). - parse hex literals at compile time (
hex()). - and, with the default
derivefeature, format types as hex (Hex/HexDebug).
This crate is used as the foundation for a number of Dusk types where a compact, allocation-free byte representation is desirable.
Features
#.- Const-generic byte sizes (e.g.
Serializable<32>). - Default helpers that work with custom error types via the
BadLengthandInvalidChartraits. - Built-in
Serializableimplementations for common integer primitives (little-endian).
Cargo features
derive(enabled by default) re-exports theHexandHexDebugprocedural macros fromderive-hex.
Consumers that only need serialization and parsing can disable default
features to keep dusk-bytes dependency-free:
= { = "0.1", = false }
Quick start
Implement [Serializable<N>] for your type:
use ;
// `DeserializableSlice` is auto-implemented for any `Serializable` type.
let p = from_slice.unwrap;
assert_eq!;
// `ParseHexStr` is also auto-implemented.
let p2 = from_hex_str.unwrap;
assert_eq!;
Hex parsing
Runtime: ParseHexStr::from_hex_str
from_hex_str parses the first N * 2 characters of a string slice (two hex
characters per byte).
- If the string is shorter than
N * 2, it returns aBadLengtherror. - If a non-hex character is found, it returns an
InvalidCharerror. - If the string is longer, extra characters are ignored.
Const-capable: hex()
hex() is a const fn that parses an ASCII hex byte string like
b"deadbeef" into a byte array. It can be called at runtime or evaluated in a
constant context.
use hex;
const MAGIC: = hex;
assert_eq!;
The input byte string must have an even length (two hex digits per byte). An
odd trailing character is rejected even if the destination is already full;
it is not ignored like extra input to from_hex_str. An odd input length or
an invalid character in the portion consumed to fill the destination panics
at runtime. When hex() is evaluated in a constant context, the same panic is
reported during compilation.
Hex formatting: Hex and HexDebug
With the default derive feature, dusk-bytes re-exports two derive macros
from the companion derive-hex crate:
#[derive(Hex)]implementscore::fmt::LowerHexandcore::fmt::UpperHex.#[derive(HexDebug)]additionally implementscore::fmt::Debugand formats the value as hex for{:?}/{:x?}/{:X?}.
Do not derive Hex or HexDebug for types containing secrets or other
confidential material. Both expose the complete to_bytes() output: Hex
through hexadecimal formatting such as {:x} and HexDebug additionally
through every Debug formatting path, including ordinary {:?}.
Both derives expect your type to expose a to_bytes() method (which the
[Serializable] trait already provides).
#
#
Readers and writers
For embedded / no_std environments, the crate provides minimal Read / Write
traits (inspired by std::io) and implements them for:
&[u8](reader)&mut [u8](writer)
use ;
let value: u32 = 0x01020304;
let mut buf = ;
let mut r = &buf;
let parsed = u32from_reader.unwrap;
assert_eq!;
assert!;
Error handling
The crate provides a small default [Error] enum that is used by the built-in
primitive implementations.
If you want to keep your own error type, implement:
- [
BadLength] (for slice/reader underflow), and - [
InvalidChar] (for hex parsing).
Those traits are used by the default implementations of DeserializableSlice
and ParseHexStr.
License
Licensed under the Mozilla Public License 2.0 (MPL-2.0).