Crate byte[][src]

A low-level, zero-copy and panic-free serializer and deserializer for binary.

Usage

First, add the following to your Cargo.toml:

[dependencies]
byte = "0.3"

Next, add this to your crate root:

extern crate byte;

Byte is no_std library; it can directly be used in a #![no_std] situation or crate.

Overview

Byte is designed for encoding or decoding binary data in a fast and low level way. A classical use case is I2C communication packages encoding.

Byte provides two core traits TryRead and TryWrite. Types implement these traits can be serialize into or deserialize from byte slices.

The library is meant to be simple, and it will always be.

Example

In this examples, we deserialize a u32 from bytes.

use byte::*;

let bytes: &[u8] = &[0xde, 0xad, 0xbe, 0xef];

let offset = &mut 0;
let num = bytes.read_with::<u32>(offset, BE).unwrap();
assert_eq!(num, 0xdeadbeef);
assert_eq!(*offset, 4);

Deserialize a str from bytes:

use byte::*;
use byte::ctx::{Str, NULL};

let bytes: &[u8] = b"hello, world!\0dump";

let offset = &mut 0;
let str = bytes.read_with::<&str>(offset, Str::Delimiter(NULL)).unwrap();
assert_eq!(str, "hello, world!");
assert_eq!(*offset, 14);

Byte supports serializing and deserializing language primitives by default.

  • &str (with context Str)
  • &[u8] (with context Byte)
  • u8, i8, u64, f64 … (with context Endian)
  • bool

Define custom serializable/deserializable type

In this example, we implement TryRead and TryWrite for type Header, which have a varibal-length name and a boolean field.

Binary Structure

|       | Length of name (Big Endian) |                Name              | Enabled |
| ----- | --------------------------- | ---- | ---- | ---- | ---- | ---- | ------- |
| Byte  | 0            | 5            | 'H'  | 'E'  | 'L'  | 'L'  | 'O'  | 0       |

Example

The only thing you may be curious to is the returned usize; it’s the number of bytes the read/write operation consumed.

use byte::*;
use byte::ctx::*;

struct Header<'a> {
    name: &'a str,
    enabled: bool,
}

impl<'a> TryRead<'a, Endian> for Header<'a> {
    fn try_read(bytes: &'a [u8], endian: Endian) -> Result<(Self, usize)> {
        let offset = &mut 0;

        let name_len = bytes.read_with::<u16>(offset, endian)? as usize;
        let header = Header {
            name: bytes.read_with::<&str>(offset, Str::Len(name_len))?,
            enabled: bytes.read::<bool>(offset)?,
        };

        Ok((header, *offset))
    }
}

impl<'a> TryWrite<Endian> for Header<'a> {
    fn try_write(self, bytes: &mut [u8], endian: Endian) -> Result<usize> {
        let offset = &mut 0;

        bytes.write_with::<u16>(offset, self.name.len() as u16, endian)?;
        bytes.write::<&str>(offset, self.name)?;
        bytes.write::<bool>(offset, self.enabled)?;

        Ok(*offset)
    }
}

Usage

let bytes = [0, 5, b"H"[0], b"E"[0], b"L"[0], b"L"[0], b"O"[0], 0];

let header: Header = bytes.read_with(&mut 0, BE).unwrap();

assert_eq!(header.name, "HELLO");
assert_eq!(header.enabled, false);

let mut write = [0u8; 8];
write.write_with(&mut 0, header, BE).unwrap();
assert_eq!(write, bytes);

Modules

ctx

Context for primitives

Structs

Iter

Iterator that read values of same type from bytes.

Enums

Error

The error type for byte crate.

Constants

BE

Big Endian byte order

LE

Little Endian byte order

Traits

BytesExt

Extension methods for byte slices.

TryRead

A data structure that can be deserialized. Types implement this trait can be read() from byte slice.

TryWrite

A data structure that can be serialized. Types implement this trait can be write() into byte slice.

Functions

check_len

A helper function that checks whether the given length exceeded the length of slice; return Err(Error::Incomplete) if not.

Type Definitions

Result

A specialized Result type for Byte