[−][src]Module packs::packable
Overview
The main API traits are Pack
and Unpack
.
Both are high-level traits for types which can be encoded and decoded
following the PackStream specification. This includes the basic types as well as
compound structures.
Encoding and Decoding Strategy
The encode
function for all basic types tries to be as space efficient as the specification
allows. E.g. an 0: i32
will get encoded just with 0x00
instead of some full Int32
. The
decode
function though reads any correct encoded value into its target type. This means,
that decode : Bytes -> Value
is not injective; different byte sequences can be decoded into
the same value:
use packs::packable::{Pack, Unpack}; let mut bytes_i16 : &[u8] = &[0xC9, 0xFF, 0xFF]; // -1 as Int16 let mut bytes_i8 : &[u8] = &[0xC8, 0xFF]; // -1 as Int8 let decoded_i16 = i64::decode(&mut bytes_i16).unwrap(); let decoded_i8 = i64::decode(&mut bytes_i8).unwrap(); assert_eq!(decoded_i8, decoded_i16);
This especially means that encode
and decode
do not need to be inverses:
use packs::packable::{Pack, Unpack}; let mut bytes : &[u8] = &[0xC9, 0x00, 0x01]; // 1 as Int16 let decoded = i64::decode(&mut bytes).unwrap(); // but will be encoded just as `TINY_PLUS_INT` here: `0x01`. let mut encoded_bytes = Vec::new(); decoded.encode(&mut encoded_bytes).unwrap(); assert_eq!(encoded_bytes.as_slice(), &[0x01]);
If the base value can only be encoded in a unique manner, then encode
and decode
are inverses:
use packs::packable::{Pack, Unpack}; let mut buffer = Vec::new(); let value: i64 = 42334388282948; value.encode(&mut buffer).unwrap(); let res = i64::decode(&mut buffer.as_slice()).unwrap(); assert_eq!(value, res);
as well as in the other direction:
use packs::packable::{Pack, Unpack}; use std::io::Cursor; let buffer: &[u8] = &[0xC9, 0x7F, 0x0C]; let mut cursor = Cursor::new(buffer); let res = i64::decode(&mut cursor).unwrap(); let mut res_buffer = Vec::new(); res.encode(&mut res_buffer).unwrap(); cursor.set_position(0); assert_eq!(cursor.into_inner(), res_buffer.as_slice());
Implementation for user-defined types
An implementation for new base types is not foreseen. Base types are built into the library itself and should be rather (pull) requested.
An implementation for complex types (i.e. structures) on the other hand, is possible and intended. Structures are packed with an extra tag byte to denote which structure is packed.
Traits
Pack | Trait to encode values into any writer using PackStream; using a space efficient way to pack. |
Unpack | Trait to decode values from a stream using PackStream. |