Skip to main content

substrate_data/wire/frame/
mod.rs

1//! Frames: data packed for messages — both sides know the schema, so
2//! nothing says what a value is or what it's called. A record's fields go
3//! in the order they're declared, after the record's length (so a reader
4//! that knows fewer fields skips the rest; one that knows more takes their
5//! defaults: fields are only ever appended). Strings go in a table at the
6//! end, each once; the body refers to them by index. `docs/format.md`
7//! ("Frames") has the layout of every value.
8//!
9//! Nothing is aligned, every value takes at least a byte (a count is
10//! checked against the bytes left), and a malformed frame reads as `None`,
11//! never a panic.
12//!
13//! ```
14//! #[derive(substrate_data::Schema, Debug, PartialEq)]
15//! struct Hit { id: String, count: u32, ratio: f32, next: Option<Box<Hit>> }
16//!
17//! let hit = Hit { id: "docs/intro".into(), count: 3, ratio: 0.5, next: None };
18//! let frame = substrate_data::frame::to_frame(&hit);
19//! assert_eq!(substrate_data::frame::read_frame::<Hit>(&frame), Some(hit));
20//! ```
21
22pub mod floats;
23pub mod lanes;
24mod packer;
25mod shaped;
26mod sizes;
27mod strings;
28mod unpacker;
29mod view;
30
31pub use packer::{Packer, to_frame};
32pub use shaped::{read_shaped, unpack_shaped};
33pub use unpacker::Unpacker;
34#[expect(
35    clippy::module_name_repetitions,
36    reason = "`frame::to_frame` and `frame::read_frame` say what they make"
37)]
38pub use unpacker::read_frame;
39pub use view::{Floats, FromF64, Ints, List, ListIter, View, list, read_view};