Expand description
A low-level, zero-copy and panic-free binary serializer and deserializer.
§Usage
First, add the following to your Cargo.toml
:
[dependencies]
byte = "0.3"
Byte
is a no_std
library; it can be used in any #![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 serialized into or deserialized from byte slices.
The library is meant to be simple, and it will always be.
§Examples
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
(withStr
context)&[u8]
(withByte
context)u8
,i8
,u64
,f64
… (withEndian
context)bool
§Define custom serializable/deserializable types
In this example, we implement TryRead
and TryWrite
for the Header
type,
which has a variable-length name and a boolean field.
§Binary Structure
| | Name's Length (Big Endian) | Name | Enabled |
| ----- | -------------------------- | ---- | ---- | ---- | ---- | ---- | ------- |
| Byte | 0 | 5 | 'H' | 'E' | 'L' | 'L' | 'O' | 0 |
§Example
The only thing you may be curious about is the returned usize; that’s the number of bytes consumed by the read/write operation.
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);
Re-exports§
Modules§
- ctx
- Context for primitives
Structs§
- Iter
- An iterator that reads values of the same type from a byte slice.
Enums§
- Error
- The error type for the
byte
crate.
Traits§
- Bytes
Ext - Extension methods for byte slices.
- TryRead
- A data structure that can be deserialized.
Types implementing this trait can be
read()
from a byte slice. - TryWrite
- A data structure that can be serialized.
Types implement this trait can be
write()
into a byte slice.
Functions§
- check_
len - A helper function that checks whether the given length exceeded the length
of the slice; returns
Err(Error::Incomplete)
otherwise.
Type Aliases§
- Result
- A specialized Result type for
Byte