Crate packtool[][src]

Expand description

packtool is a packing library. Useful to define how serializing and deserializing data from a type level definition.

Example

Unit types

unit types can be packed. What this means is that the object is known to have the same constant value. That way it is possible to define values that are expected to be found and to be the same.

All Packed unit structures must have a #[packed(value = ...)] attribute. The value can be set to any literal except: bool, float.

use packtool::{Packed, View};

/// a unit that is always the utf8 string `"my protocol"`
/// and takes 11 bytes in the packed structure
#[derive(Packed)]
#[packed(value = "my protocol")]
pub struct ProtocolPrefix;

/// a unit that is always `4` and takes 1 byte long
#[derive(Packed)]
#[packed(value = 0b0000_0100u8)]
pub struct OtherUnit();

/// a unit that is always `0xcafe` and takes 4 bytes
/// in the packed structure
#[derive(Packed)]
#[packed(value = 0xcafeu32)]
pub struct LastButNotLeast {}

const SLICE: &[u8] = b"my protocol";
let view: View<'_, ProtocolPrefix> = View::try_from_slice(SLICE)?;

Here we are expecting the ProtocolPrefix to always have the same value in the packed representation. When serializing the ProtocolPrefix, the value will be set with these 11 characters.

combining packed objects

It is possible to compose packed objects in named or tuple structures.

use packtool::Packed;

#[derive(Packed)]
#[packed(value = "packcoin")]
pub struct Tag;

/// 1 byte that will be used to store a version number
#[derive(Packed)]
#[repr(u8)]
pub enum Version {
    V1 = 1,
    V2 = 2,
}

/// 8 bytes that will be used to store a block number
#[derive(Packed)]
pub struct BlockNumber(u32, u32);

/// 9 bytes packed header
#[derive(Packed)]
pub struct Header {
    tag: Tag,
    version: Version,
    block_number: BlockNumber
}

Enumeration

Only enumerations without fields are allowed for now.

use packtool::{Packed, View};

#[derive(Packed)]
#[repr(u8)]
pub enum Version {
    V1 = 1,
    V2 = 2,
}

let view: View<'_, Version> = View::try_from_slice(SLICE)?;

assert!(matches!(view.unpack(), Version::V1));

the repr(...) is necessary in order to set a size to the enum.

use packtool::Packed;

#[derive(Packed)]
pub enum Color {
    Red = 1,
    Green = 2,
    Blue = -1
}

Macros

ensure

helper method to create an [Error] is the assumption fails.

Structs

Packet

a owned slice of memory containing the Packed

View

view of a slice in memory as a packed structure of type T

Enums

Error

error associated to unpacking or creating [View] of [Packed] types.

Traits

Context
Packed

trait to define how a fixed size Packed object is serialized into a byte slice representation.

Derive Macros

Packed