Expand description
petra
is a simple binary encoding library with support for flexible containers.
Heavily inspired by MessagePack, petra
aims to provide more or less the same features with an additional goal of supporting flexible maps and arrays.
There are both advantages and disadvantages associated with such a feature, therefore petra
might not be the right tool for many jobs, but it is a useful tool to have around nevertheless.
In a similar fashion to MessagePack, petra
uses 8-bit Marker
s to delimit and discriminate data.
Markers are defined for a variety of data types and representations.
Each piece of data is preceeded by a marker identifying the type and lenght of the data.
For more information on the encoding format, please see the specifications.
§Buffers
Two buffer variants are provided by the library: ReadBuffer
and WriteBuffer
.
These buffers are at the core of the entire encoding and decoding mechanics of the library.
They wrap around references to data and provide reading and writing capabilities with cursor tracking and a few more features.
§Encoding and decoding
The decode
and encode
modules provide low-level functions for reading and writing directly to and from ReadBuffer
and WriteBuffer
instances.
The higer-level de
and ser
modules provide standard Serializer
and Deserializer
implementations for working for arbitrary data types.
§Examples
§Serialization from a struct and manual data decoding
use serde::Serialize;
use petra::decode::*;
use petra::{Marker, ReadBuffer, WriteBuffer};
use petra::ser::Serializer;
#[derive(Serialize)]
struct Foo {
x: u8,
y: String,
}
let mut data = [0u8; 1024];
let mut buffer = WriteBuffer::from(&mut data);
let mut ser = Serializer::from_buffer(&mut buffer);
let foo = Foo { x: 42, y: "it works".into() };
foo.serialize(&mut ser);
let mut buffer = buffer.into_read_buffer();
// The struct `foo` is encoded as a map with two elements.
assert_eq!(read_map(&mut buffer), Ok(Some(2)));
// The keys in the map are the field names.
// The values are u8 and str.
// The first field.
assert_eq!(read_str(&mut buffer), Ok("x"));
assert_eq!(read_unsigned(&mut buffer), Ok(42));
// The second field.
assert_eq!(read_str(&mut buffer), Ok("y"));
assert_eq!(read_str(&mut buffer), Ok("it works"));
§Manual data encoding and deserialization into a struct
use serde::Deserialize;
use petra::encode::*;
use petra::{Marker, ReadBuffer, WriteBuffer};
use petra::de::Deserializer;
#[derive(Debug, Deserialize, PartialEq)]
struct Foo<'a> {
a: u16,
#[serde(borrow)]
b: Vec<&'a str>,
c: bool,
}
let mut data = [0u8; 1024];
let mut buffer = WriteBuffer::from(&mut data);
// The struct `foo` is encoded as a map with three elements.
assert!(matches!(write_map(&mut buffer, Some(3)), Ok(Marker::ImmMap { len: 3 })));
// The keys in the map are the field names.
// The values are of types u16, flexible array of String, and bool.
// The first field.
assert!(matches!(write_str(&mut buffer, "a"), Ok(Marker::ImmStr { len: 1 })));
assert!(matches!(write_unsigned(&mut buffer, 1024), Ok(Marker::U16)));
// The second field.
assert!(matches!(write_str(&mut buffer, "b"), Ok(Marker::ImmStr { len: 1 })));
assert!(matches!(write_array(&mut buffer, None), Ok(Marker::AFlex)));
// Now we may encode any number of array elements of type String, let's say 2 elements.
{
assert!(matches!(write_str(&mut buffer, "first"), Ok(Marker::ImmStr { len: 5 })));
assert!(matches!(write_str(&mut buffer, "second"), Ok(Marker::ImmStr { len: 6 })));
}
// And we terminate the flexible array.
assert!(matches!(write_terminator(&mut buffer), Ok(Marker::Term)));
// The last field.
assert!(matches!(write_str(&mut buffer, "c"), Ok(Marker::ImmStr { len: 1 })));
assert!(matches!(write_bool(&mut buffer, true), Ok(Marker::Bool { value: true })));
let mut buffer = buffer.into_read_buffer();
let mut de = Deserializer::from_buffer(&mut buffer);
assert_eq!(
Foo::deserialize(&mut de),
Ok(Foo {
a: 1024,
b: vec!["first", "second"],
c: true,
}),
);
Modules§
- de
serde
- Arbitrary data deserialization.
- decode
- Low-level primitives for data decoding.
- encode
- Low-level primitives for data encoding.
- ser
serde
- Arbitrary data serialization.
Structs§
- Read
Buffer - A read buffer with cursor, peaking, borrowing and last read undo.
- Snapshot
- A snapshot of the cursor position within a buffer.
- Write
Buffer - A write buffer with cursor, last write undo and error flag.