[−][src]Crate byte
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 contextStr)&[u8](with contextByte)u8,i8,u64,f64... (with contextEndian)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 |
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 |
| TryWrite | A data structure that can be serialized. Types implement this trait can be |
Functions
| check_len | A helper function that checks whether the given length
exceeded the length of slice; return |
Type Definitions
| Result | A specialized Result type for |