SPUD (Structured Payload of Unintelligible Data)
SPUD is a custom binary file format designed for efficient storage and transmission of structured data. It uses type tags and field name interning to achieve a compact representation. This implementation is written in Rust.
Features
- Compact Binary Representation: Uses binary encoding for data types.
- Basic Data Types: Supports
null,boolean, various integer (i8-i64,u8-u64) and float (f32,f64) types, strings, and raw binary blobs. - Field Name Interning: Assigns unique IDs to field names within a file to reduce redundancy and save space.
- Versioning: Files start with a version identifier (set at compile time) to ensure compatibility.
- Simple Structure: Consists of a version header, a field name map, the data payload, and an End-Of-File marker (
[0xDE, 0xAD, 0xBE, 0xEF]). - Serde Integration: Seamless conversion between Rust structs and the SPUD format via
serde.
File Structure
A .spud file generally follows this structure:
- Version String: The version string (bytes).
- Field Name Map:
- A sequence of
(length_byte, field_name_bytes, id_byte). - Ends with the
FieldNameListEndmarker (0x01).
- A sequence of
- Data Payload:
- A sequence of
(FieldNameId_marker, field_id_byte, type_tag_byte, value_bytes). - String and BinaryBlob types include their length before the data.
- Arrays and Objects are delimited by
ArrayStart,ArrayEnd,ObjectStart, andObjectEndtype tags.
- A sequence of
- EOF Marker: The sequence
0xDE, 0xAD, 0xBE, 0xEF.
Usage
Encoding (Creating a SPUD file)
You can build SPUD files either manually or by serializing Rust structs with serde.
Manual Usage
use SpudBuilder;
let mut builder = new;
builder
.add_value
.add_value
.add_value
.add_value
.add_value
.add_value;
builder.build_file;
println!;
Serde Usage
use SpudBuilder;
use Serialize;
let data = MyData ;
let mut builder = from_serde;
builder.build_file;
Decoding (Reading a SPUD file)
You can decode SPUD files manually or deserialize them into Rust structs with serde.
Manual Usage
use SpudDecoder;
let mut decoder = new_from_path;
println!;
decoder.decode;
println!;
Serde Usage
use SpudDecoder;
use Deserialize;
let mut decoder = new_from_path;
let data: MyData = decoder.deserialize.unwrap;
Roadmap / TODO
Here are some planned features and improvements:
- [ ]
serdeIntegration: Implementedserde::SerializeforSpudBuilderandserde::DeserializeforSpudDecoder. - [ ] More Types: Support for timestamps, decimals, or other common data types if needed.
Known bugs
There are some bugs that are yet to be fixed:
- Order of field: Even if i'm using an IndexMap to order the fields, the order is still not correct
Contributing
Contributions are welcome! Please open an issue to discuss changes or submit a pull request.