Skip to main content

Crate rapira

Crate rapira 

Source
Expand description

§Rapira

A fast, safe binary serialization library — an alternative to bincode, borsh and speedy, tuned for compactness and speed with built-in safety checks. Supports no_std (disable default features, enable alloc as needed).

§Quick start

use rapira::{Rapira, serialize, deserialize};

#[derive(Rapira, PartialEq, Debug)]
struct Point {
    x: u32,
    y: u32,
}

let bytes = serialize(&Point { x: 1, y: 2 });
let decoded: Point = deserialize(&bytes).unwrap();
assert_eq!(decoded, Point { x: 1, y: 2 });

§The Rapira trait

The core trait. Key members:

  • size(&self) -> usize — serialized byte length.
  • check_bytes(slice) -> Result<()> — validate untrusted bytes (UTF-8, collection bounds, NonZero, float finiteness) before decoding.
  • from_slice(slice) -> Result<Self> — safe decode (checks capacity limits).
  • convert_to_bytes(&self, slice, cursor) — encode into a preallocated buffer.
  • STATIC_SIZE: Option<usize>Some(n) for fixed-size types, None for dynamic.

§Deserialization safety tiers

MethodChecksUse for
from_slicecapacity limitsuntrusted / external data
from_slice_uncheckedcursor bounds only (skips UTF-8 / float / NonZero)trusted data
from_slice_unsafenoneonly after check_bytes

§Top-level API

serialize / deserialize, check_bytes, extend_vec, and the context-aware serialize_ctx / deserialize_ctx (which carry RapiraFlags — e.g. the id-encryption flag used at a wire boundary).

§Wire format

  • Little-endian integers; usize as u32, isize as i64.
  • Collection / string lengths as u32 (LEN_SIZE = 4 bytes).
  • f32 / f64 must be finite (NaN / Inf → error).
  • Option<T>: 1-byte discriminant + payload. Enums: 1-byte tag + payload.
  • Duration: seconds only (nanoseconds discarded).

§Derive macros

#[derive(Rapira)] generates the trait impl. The crate also provides #[derive(FromU8)] and #[derive(PrimitiveFromEnum)] for enum ↔ byte conversion (see FromU8).

§#[derive(Rapira)] attributes

Container (struct / enum):

AttributeEffect
#[rapira(static_size = expr)]override the computed STATIC_SIZE
#[rapira(min_size = expr)]override the computed minimum size
#[rapira(version = N)](struct) enable versioned deserialization; pairs with field since (see from_slice_versioned)
#[rapira(peer)](feature schema) generate a PeerRead impl for forward-compatible decoding; the type must also implement GetType
#[rapira(debug)]print the generated code at compile time
#[primitive(PrimEnum)](complex enum) take discriminants from a sibling unit enum

Field:

AttributeEffect
#[rapira(with = path)](de)serialize via module fns (e.g. byte_rapira, bytes_rapira, str_rapira, rapira::zero) instead of the field’s Rapira impl
#[rapira(skip)]skip the field; Default::default() on decode
#[rapira(since = N)]field added in schema version N (requires version on the struct; the field type must implement Default)

Enum variant:

AttributeEffect
#[idx = N]set the variant’s wire tag explicitly
#[rapira(unknown)](feature schema, on a #[rapira(peer)] enum) one unit variant used as the fallback for variants an older reader doesn’t know; not allowed on #[primitive] enums
#[derive(Rapira)]
#[rapira(version = 2)]
struct User {
    id: u64,
    #[rapira(with = rapira::byte_rapira)]
    kind: u8,                   // encoded via byte_rapira, not the u8 impl
    #[rapira(since = 2)]
    nickname: Option<String>,   // added in v2; v1 data decodes it as None
    #[rapira(skip)]
    cached: u32,                // never on the wire; Default on decode
}

§Schema-aware forward-compat (feature schema, default)

PeerRead decodes a value against a sender-provided runtime schema (armour_typ::SchemaTyp) so additive changes (new fields, new enum variants) don’t break older readers. Scalars, ids and collections implement it already; a domain struct / enum opts in with #[rapira(peer)], and an enum may mark one unit variant #[rapira(unknown)] as the unknown-variant fallback. Entry point: deserialize_with_peer / deserialize_with_peer_ctx. Dispatch on the schema hash (armour_typ::schema_hash): equal hashes → plain deserialize; differing → pass the peer schema. See docs/rapira.md for the full guide (including which types get PeerRead automatically vs by opt-in).

§Feature flags

Default: std, zerocopy, serde / serde_json, arrayvec, bytes, time, schema. Optional: smallvec, indexmap, rust_decimal, compact_str, smol_str, ecow, uuid, bytemuck, inline-array, fjall, byteview, postcard, solana, rmp.

Re-exports§

pub use error::RapiraError;
pub use error::Result;
pub use funcs::check_bytes;
pub use funcs::deser_unchecked;
pub use funcs::deser_unsafe;
pub use funcs::deserialize;
pub use funcs::deserialize_ctx;
pub use funcs::deserialize_versioned;
pub use funcs::size;
pub use funcs::size_ctx;
pub use funcs::deserialize_with_peer;
pub use funcs::deserialize_with_peer_ctx;
pub use funcs::extend_vec;
pub use funcs::serialize;
pub use funcs::serialize_ctx;

Modules§

byte_rapira
bytes_rapira
for all similar &u8
error
funcs
max_cap
schema
str_rapira
for all similar &str
zero

Macros§

deser
usage: let (b1, c1, a1) = deser!(bytes, str_rapira, byte_rapira | u32)
ser
usage: let bytes = ser!((a, str_rapira), (&b, byte_rapira) | &c)

Structs§

EnumFromU8Error
RapiraFlags
Bitflags for context-aware serialization. Bits 0–7 are reserved for rapira. External crates use bits 8+.

Constants§

LEN_SIZE

Traits§

FromU8
PeerRead
Schema-aware deserialization for types that can decode bytes using a peer-provided runtime schema.
Rapira

Functions§

enum_min_size
enum_size
extend
min_size
push
static_size
try_extend
try_push

Derive Macros§

FromU8
PrimitiveFromEnum
#[primitive(PrimitiveName)]
Rapira
available attributes: