1 unstable release
Uses new Rust 2024
new 0.1.0 | Apr 17, 2025 |
---|
#4 in #enabled
80KB
1.5K
SLoC
dataparser_core
This crate is not 100% finished, and you may encounter bugs that I missed!
A flexible and efficient binary parsing and serialization library for Rust. This crate is intended to serve as the foundation for parsers, encoders, and binary protocol implementations, and is designed to be extensible, testable, and compatible with both synchronous and asynchronous I/O. Inspired by nom <3
Features
- Zero-copy binary parsing
- Declarative combinator-style parser utilities (WIP)
- Procedural macros for
#[derive(StructDeserialize, StructSerialize)]
(Accessible via thederive
feature) - Optional async I/O support using
tokio::io::AsyncWrite
(WIP, accessible via theasync
feature)
Crate Overview
The crate is divided into the following modules:
parser::core
– TheDataParser
type and parser combinatorsencoder::core
– TheDataEncoder
andDataWriter
types for serializationtraits
– ContainsEncodable
,Decodable
, andAsyncEncodable
traits (If using theasync
feature)errors
– Unified error handling for parser and encoder logic
Crate Features
derive
: Enables the usage ofStructDeserialize/StructSerialize
for serializing/deserializing structsasync
: (WIP) Enables support for asynchronous readers/writers via tokiocrypto
: (WIP) Enables encrypting/decrypting the buffer viaAES-256-CBC
encryption. Working on adding a more dynamic approach to this
Custom Encoding
You can implement custom encoders for types via the Encodable
trait
struct MyType {
id: u32,
name: String
}
impl Encodable for MyType {
fn encode_data(&self, encoder: &mut DataEncoder) -> ParseResult<()> {
encoder.add_u32(self.id)?;
encoder.add_string(&self.name)?;
Ok(())
}
}
Example: Deserialization
This will only work if you have the derive
feature enabled!
use dataparser_core::parser::core::DataParser;
use dataparser_core::parser::traits::Decodable;
#[derive(StructDeserialize, Debug)]
struct Message {
id: u32,
name: String,
values: Vec<u16>,
is_active: bool,
}
fn main() -> io::Result<()> {
let raw_data: &[u8] = vec![/* binary input */].as_slice();
let mut parser = DataParser::new(raw_data);
let message = Message::from_parser(&mut parser)?;
Ok(())
}
Example: Serialization
This will only work if you have the derive
feature enabled!
use dataparser_core::encoder::core::DataEncoder;
use dataparser_core::encoder::helpers::Encodable;
#[derive(StructSerialize)]
struct Payload {
timestamp: u64,
payload: Vec<u8>,
}
fn main() -> io::Result<()> {
let payload = Payload { timestamp: 123456, payload: vec![1, 2, 3] };
let mut encoder = DataEncoder::default();
payload.encode_data(&mut encoder)?;
let bytes = encoder.get_data()?;
Ok(())
}
Installation
Add this to your Cargo.toml
file:
dataparser_core = "0.1.0"
Or alternatively, using cargo
:
cargo add dataparser_core
License
MIT
Dependencies
~0.2–6.5MB
~41K SLoC