A statically determined serialization and deserialization system for sized types.
This crate is intended for use in no_std
environments.
This crate creates two traits: Serialize
and Deserialize
.
They are extremely simple:
pub trait Serialize<const N: usize>: Sized {
fn serialize(self) -> [u8; N];
}
pub trait Deserialize<const N: usize>: Sized {
fn deserialize(data: [u8; N]) -> Option<Self>;
}
As you can see, since these traits are restricted to sized types, the size of the serialized representation (N
) is known as well.
Two convenience derive macros Serialize
and Deserialize
are provided and can be used like so:
#[derive(Serialize, Deserialize)]
#[repr(u16)]
enum Foo {
A,
B(bool) = 0xde,
C(u8)
}
#[derive(Serialize, Deserialize)]
struct Bar {
a: u8,
foo: Foo,
b: u16
}
Since
Foo
implementsSerialize
andDeserialize
,Bar
can as well.
No unsafe
blocks are used in this crate. The derive macros cannot generate unsafe code. Worst case their output will just not compile.
The derive macros are a zero-cost abstraction. They employ constant evaluation to generate static code that extracts bytes from inner structures and places it into the result array. No counting pointer, no runtime checks (other than that of array::copy_from_slice(...)
), direct insertion only.