Crate binext

Source
Expand description

binext is a library that aims to make easier working with binary buffers and structs like you would in C.

This library provides safe interfaces to write/read structs from Read/Write binary sources.

If used along with #[repr(C)], this crate allows to read/write binary structures between C/C++ and Rust.

Reading from/to a buffer is as easy as the following:

use binext::{BinaryWrite, BinaryRead};
use std::{io, fs::OpenOptions};

#[derive(Debug, Default)] // This is just to avoid creating all fields manually.
struct MyStruct {
    a: u32,
    b: i16,
    c: char
}

fn main() -> io::Result<()> {
    let mut write_file = OpenOptions::new()
        .write(true)
        .create(true)
        .truncate(true)
        .open("somefile.bin")?;

    let item = MyStruct {
        a: 256,
        ..Default::default()
    };

    // Write the item into the file.
    write_file.write_binary(&item)?;

    // Drop both the file and the item.
    drop(write_file);
    drop(item);

    let mut read_file = OpenOptions::new()
        .read(true)
        .open("somefile.bin")?;

    // This item has the same data as the previous one.
    let new_item = read_file.read_binary::<MyStruct>()?;

    println!("{new_item:?}");

    Ok(())
}

However, it is not limited to files, any type implementing Read/Write implements BinaryRead/BinaryWrite respectively.

For example, we could use a Vec<u8> which is Write, to write in it and then wrap it with a Cursor to make it Read and read it’s contents into another instance:

use binext::{BinaryWrite, BinaryRead};
use std::io::{self, Cursor};

#[derive(Debug)]
struct MyStruct {
    a: u32,
    b: i16,
    c: char
}

fn main() -> io::Result<()> {
    let item = MyStruct {
        a: 256,
        c: '.',
        b: 128
    };

    let mut buffer = Vec::new();

    // Write struct into the buffer.
    buffer.write_binary(&item)?;
    drop(item);

    // In order to make a Vec<u8> Read, a cursor must be used.
    let mut  cursor = Cursor::new(buffer);

    // Now we read the contents of the previous instance back.
    let recovered = cursor.read_binary::<MyStruct>()?;

    println!("{recovered:?}");

    Ok(())
}

Traits§

BinaryRead
The BinaryRead trait allows for reading data structures out of binary sources.
BinaryWrite
The BinaryRead trait allows for writing data structures into binary Write sources.