Imported from dusk-network/dusk-bytes (
AGENTS.md). Install upstream withnpx skills add dusk-network/dusk-bytes. Copyright stays with the author.
dusk-bytes
Serialization traits using const generics for fixed-size types. Workspace with two no_std crates: core serialization traits and a companion proc-macro for hex formatting. This is a foundational dependency for most Dusk repos — changes here ripple widely.
Repository Map
bytes/
├── dusk-bytes/ # dusk-bytes — Serializable<N>, DeserializableSlice, Read/Write, hex parsing
│ ├── src/
│ │ ├── lib.rs # Re-exports, crate attributes
│ │ ├── serialize.rs # Serializable<N>, DeserializableSlice, Read, Write traits
│ │ ├── parse.rs # ParseHexStr trait, const hex() function
│ │ ├── errors.rs # Error enum, BadLength/InvalidChar traits
│ │ └── primitive.rs # Serializable impls for integer primitives (u8..u128, i8..i128)
│ └── tests/
├── derive-hex/ # derive-hex — #[derive(Hex)] and #[derive(HexDebug)] proc macros
│ ├── src/
│ │ └── lib.rs # LowerHex, UpperHex, Debug derive implementations
│ └── tests/
├── Makefile # Build targets (run `make help`)
└── rustfmt.toml
Commands
Run make help to see all available targets.
Architecture
Core Traits (dusk-bytes)
Serializable<const N: usize>— definesfrom_bytes(&[u8; N])andto_bytes() -> [u8; N]for fixed-size serialization. The const genericNis the wire size.DeserializableSlice<N>— auto-implemented for allSerializable<N>types. Addsfrom_slice(&[u8])(with length check) andfrom_reader<R: Read>()(streaming).Read/Write— minimal byte-oriented IO traits (notstd::io).Readis implemented for&[u8](advances the slice),Writefor&mut [u8].ParseHexStr<N>— auto-implemented for allSerializable<N>types. Parses hex strings into the target type.hex::<N, M>()— const function for compile-time hex-to-bytes conversion.
Proc Macros (derive-hex)
#[derive(Hex)]— generatesLowerHexandUpperHeximplementations using the type'sto_bytes()method.#[derive(HexDebug)]— generatesHexplus aDebugimplementation that delegates to hex formatting.
Key Design Points
- All serialization is little-endian (see primitive impls).
derive-hexis a proc-macro crate — it cannot be built forno_stdtargets likethumbv6m-none-eabi. The defaultdusk-bytesderivefeature re-exports its macros; disabling default features leaves the serialization crate dependency-free. Theno-stdMakefile target builds that minimal configuration.
Conventions
no_std: Both crates. Do not addstddependencies.- Edition 2024: The workspace uses Rust edition 2024 with MSRV 1.96.1.
- Wide downstream impact: This crate is a dependency of most Dusk repos. Check
Cargo.lockin downstream repos before releasing. See the Change Propagation table below.
Change Propagation
| Changed | Also verify |
|---|---|
dusk-bytes or derive-hex |
Most repos — check Cargo.lock for users. Key dependents: bls12_381, jubjub, phoenix, safe, Poseidon252, merkle, rusk |
Git Conventions
- Default branch:
main - License: MPL-2.0
Commit messages
Format: <scope>: <Description> — imperative mood, capitalize first word after colon.
One commit per crate per concern. Each commit touches exactly one crate and one logical concern. Never bundle changes to different crates in one commit, and don't mix unrelated changes within the same crate either.
Canonical scopes:
| Scope | Crate/Directory |
|---|---|
dusk-bytes |
dusk-bytes/ |
derive-hex |
derive-hex/ |
workspace |
Root Cargo.toml, root Makefile |
ci |
.github/workflows/ |
chore |
Makefile, rustfmt, etc. |
Examples:
dusk-bytes: Add Read impl for Vec<u8>derive-hex: Fix category slugsworkspace: Update edition to 2024
Changelog
Both crates have a CHANGELOG.md. Add entries to the affected crate under
[Unreleased] using Keep a Changelog format. If
a change traces to a GitHub issue, reference it as a link:
[#42](https://github.com/dusk-network/dusk-bytes/issues/42). Only link to
GitHub issues — do not reference any other tracking system.