[−][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 |