Skip to main content

Module serde_helpers

Module serde_helpers 

Source
Expand description

serde integration for every decimal width.

D38 has a dedicated Serialize / Deserialize pair plus the richer decimal_serde::DecimalVisitor used for #[serde(with = "...")] field annotations. The wide tiers (D76 / D153 / D307) use a slimmer implementation emitted by decl_wide_serde!: a decimal-string wire format for human-readable serializers and a little-endian limb-bytes wire format for binary serializers. Cross-tier wire-format parity is intentional — a D38 produced at SCALE = 12 serialises to the same string as a D76 at SCALE = 12 carrying the same logical value.

§Wire format

D38<SCALE> chooses its wire encoding based on the serializer’s serde::Serializer::is_human_readable flag:

  • Human-readable formats (JSON, TOML, YAML): a base-10 integer string of the underlying i128 storage value. For example, D38s12::ONE (storage 1_000_000_000_000) serialises as the JSON string "1000000000000". This is not a decimal string like "1.0" — that is the job of Display, not the wire format.

A string rather than a JSON number is used because JSON numbers are effectively f64 in most runtimes (max safe integer = 2^53 - 1), while i128 storage requires up to 127 bits. A BigInt-compatible integer string is the only lossless option for interoperability with JavaScript, where BigInt(s).toString() round-trips the same digits.

  • Binary formats (postcard, bincode, etc.): 16 little-endian bytes from i128::to_le_bytes. Compact and endian-canonical.

On deserialise, the internal DecimalVisitor handles both wire forms plus visit_i64 / visit_u64 / visit_i128 / visit_u128 callbacks, which are used when the underlying format yields a native integer. The integer is interpreted directly as the scaled i128 storage.

Modules§

decimal_serde
Serde helper module for #[serde(with = "...")] field annotations.