Serac
A static, modular, and light-weight serialization framework.
Encoders specify what kind of serialization medium they can target, and define the serialization or deserialization process for that medium.
Serac comes with one built-in encoder Vanilla.
Why not serde?
Serac's value proposition is its ability to perform static analysis on serialization participants to either refine the failure space, or guarantee infallibility.
Examples
Serialize a number
use ;
let number = 0xdeadbeefu32;
let mut buf = buf!; // [0; 4] in this case.
number.serialize_iter.unwrap;
let readback = deserialize_iter.unwrap;
assert_eq;
The "Vanilla" encoding is used by default unless otherwise specified.
In the above example, there was an unwrap used on the result of serialize_iter
because the buffer could have been too short.
Using SerializeBuf, we can avoid this:
use ;
let number = 0xdeadbeefu32;
let mut buf = buf!;
number.serialize_buf; // it is statically known that "u32" fits in "[u8; 4]"
// it is *not* statically known that all values of "[u8; 4]" produce a valid "u32",
// and only that failure mode is expressed
let readback = deserialize_buf.unwrap;
assert_eq;
Many built in types like numbers, tuples, and arrays implement both SerializeIter
and SerializeBuf.
Serialize a custom type
use ;
const BE: u8 = 0xbe;
let foo = D ;
let mut buf = buf!;
foo.serialize_buf;
let readback = deserialize_buf.unwrap;
assert_eq;
This example shows a crazy enum with lots of fancy things going on, which is able to be serialized by serac.
Serialize a custom generic type
Mostly, the serialization of generic types is the same:
use ;
const BE: u8 = 0xbe;
let foo = B ;
let mut buf = buf!;
foo.serialize_iter.unwrap;
let readback = deserialize_iter.unwrap;
assert_eq;
// ...
But SerializeBuf is not derivable on generic types.
You can, however, implement SerializeBuf for concretely specified aliases of
generic types:
// ...
type ConcreteFoo = ;
let foo = B ;
let mut buf = buf!;
foo.serialize_buf;
let readback = deserialize_buf.unwrap;
assert_eq;