#marshalling #format #serde #stupid #type #value #value-only

no-std ssmarshal

Stupid simple value-only marshaling using serde

2 releases (1 stable)

Uses old Rust 2015

1.0.0 May 13, 2017
0.0.1 Jan 4, 2017

#913 in Encoding

Download history 3385/week @ 2024-02-28 3633/week @ 2024-03-06 3344/week @ 2024-03-13 4239/week @ 2024-03-20 4585/week @ 2024-03-27 4065/week @ 2024-04-03 3998/week @ 2024-04-10 2981/week @ 2024-04-17 2708/week @ 2024-04-24 3535/week @ 2024-05-01 3450/week @ 2024-05-08 2583/week @ 2024-05-15 3002/week @ 2024-05-22 3792/week @ 2024-05-29 2378/week @ 2024-06-05 2576/week @ 2024-06-12

12,390 downloads per month
Used in 32 crates (10 directly)

MIT/Apache

29KB
646 lines

ssmarshal

Crates.io

Documentation

ssmarshal ("stupid simple marshaling") is a serde-based de/serialization library. It is somewhat like bincode, but doesn't support String/Vec - this library is entirely zero-allocation, for use in extremely limited no_std contexts. The key invariant is that the encoding space for any value of a type is <= size_of::<T>(). This allows easy reasoning about limited buffer sizes, and how much is always enough.

Limitations

These sorts of types are not supported:

  • Any non-core type (eg, Vec, HashMap)
  • Slices
  • Strings
  • Types containing references or pointers
  • Enums with more than 256 variants

All enums MUST be #[repr(C)] in order for the size invariant to be upheld. Note that this excludes using Option, especially with NonZero types! You can use this crate with non-#[repr(C)] enums, but you should thoroughly test (I recommend quickcheck, see the tests for an example) de/serializing values of that type to be assured the size invariant holds for the type.

Details of the format

The format is not incredibly compact, but doesn't add extra fluff, and is quick to en/decode.

  • bool is serialized as a byte, 1 if true, 0 is false.
  • the integer types are encoded in their little-endian form.
  • f32 is bitcast to a u32 then encoded as a u32. likewise, f64 and u64.
  • inhabited enums are serialized as 1 byte for the discriminant, and then the fields.
  • structs are serialized as just their fields.
  • the unit type and uninhabited enums are not serialized at all.
  • tuples are serialized as the fields, in order.

There is no padding.

As you might see, this format is not self-describing. To successfully deserialize a value, the exact layout must be known ahead-of-time.

Alternatives

This is designed for doing IPC in a microkernel, with a stable ABI, not saving to disk or transferring over the network. It may be useful for those cases, although you'll likely want a format which can handle data evolution, like Cap'n Proto.

If you care about truly minimizing encoding space, you might look into ASN.1 PER.

If you need more features (for example, slices or references), but still don't care about data evolution, I recommend using bincode.

Testing

The roundtrip test suite exercises almost all of the functionality of ssmarshal, with coverage over 95% (missing mostly some of the error cases for invalid/unsupported types).

This library is extensively fuzz tested with cargo-fuzz (libFuzzer) before every release. See the fuzz directory for the scripts used.

Dependencies

~255–500KB