datalit

Crates.iodatalit
lib.rsdatalit
version0.1.0-alpha.4
created_at2025-09-12 05:28:21.004621+00
updated_at2025-09-14 19:26:49.059628+00
descriptionA zero-runtime fluent data description macro
homepage
repositoryhttps://github.com/naerbnic/datalit
max_upload_size
id1835197
size24,994
(naerbnic)

documentation

https://docs.rs/datalit

README

datalit

Crates.io docs.rs CI License: MIT/Apache-2.0 MSRV

Overview

datalit provides the datalit!(...) macro to turn a readable list of things into real bytes at compile time. Highlights:

  • Readable data: Hard to read raw byte arrays? Describe intent with readable literals.
  • Endian aware: Can't read bytes backwards? Declare the endianness; the macro handles the rest.
  • Offsets: Tired of recalculating offsets? Labels and offset expressions update themselves.
  • Concise: Spending time on padding & length management? Built-ins remove the manual bookkeeping.
  • Zero cost at runtime: Worried about hidden cost or mistakes? Your data is validated at compile time, and expands to one static slice.

Installation

datalit can be added using the standard cargo add command:

$ cargo add datalit
...

Usage

In your code, you can use a datalit macro as an expression. This will resolve to a reference to a static array that contains the data described by the contents of the macro.

Examples

use datalit::datalit;

let data = datalit!(
  // Hex / binary literals of any length (whole bytes) appended L->R.
  0xDEAD_BEEF_CAFE_BABE,
  0b0110_1111_1000_0100,

  // Primitive integers: native endian by default.
  1u32, 0x1FFu16,

  // Explicit endianness via suffix or mode.
  100u16_le,
  @endian = be,
  42u32,           // big-endian now

  // Non-standard width.
  0x01_02_03u24_be,

  // Strings / bytes.
  b"quux", b'X', c"Hello, world!",

  // Alignment to next multiple of 8 (pads with 0x00)
  align(8),

  // A labeled block and offset expressions.
  start('payload): u16_le,
  'payload: {
    12u16,
    b"PAY",
  },
  end('payload): u16_le,
  len('payload): u16_le,

  // Simple & compound arrays.
  [ 0xFF; 4 ],
  [{ 0xAA, 0xBB }; 2],
);
assert!(data.len() > 0);

Contributing

Contributions are welcome! If you’ve got a bug report, idea, or small fix:

  • Use the issue templates to file bugs or propose features.
  • For small docs or code tweaks, open a PR directly.
  • For larger changes (new syntax, behavior, or breaking changes), please open an issue or discussion first so we can align on design.

Before you open a PR, please:

  • Run formatting and lints (we deny warnings) and the test/docs suites.
  • Keep the public crate no_std and forbid(unsafe_code) guarantees intact.
  • Add or update tests and docs for user-visible changes.

See CONTRIBUTING.md for details on the workflow and guidelines.

License

This project is dual-licensed under either the MIT or Apache 2.0 license, at your option.

You may use this project under the terms of either license.

Security

Please do not report vulnerabilities in public issues. For private disclosure instructions, see SECURITY.md.

Acknowledgements

Thanks to the Rust macros and tooling ecosystem—particularly syn, quote, and proc-macro2—for making ergonomic proc-macros possible.

And thanks in advance to contributors for bug reports, ideas, and reviews.

Future work

  • Allow for scoped labels, so they can be used in compound arrays.
  • Add basic math operators, so things like relative offsets or the like can be computed.
  • Allow for alignment to define the fill byte (or make it part of the mode)
  • Implement scoped modes, so mode changes within a block can be made without affecting the outside state.
  • Allow for some relatively common specialized operations, such as CRCs
  • Allow labeled range offsets to be exported along with the data so runtime code can use it as needed.
  • Support for strings, including with multiple encodings
  • Syntax: Have a paren-wrapped entry be treated as an expression (with function calling as a special case)
Commit count: 65

cargo fmt