#binary-encoding #serialization #binary #version #decode #encode

nightly macro binverse_derive

Macros for the binverse crate providing fast binary serialization with versioning

12 unstable releases (3 breaking)

0.6.2 Feb 3, 2022
0.6.1 Jan 15, 2022
0.5.5 Jan 8, 2022
0.5.2 Nov 2, 2021
0.3.0 Oct 19, 2021

#117 in #binary-encoding


Used in binverse

MIT license

21KB
352 lines

BinVerSe (Binary Versioned Serializer)

Provides fast binary serialization with versioning to store data in a backwards-compatible, compact way.

Right now, the crate is still work in progress and I wouldn't recommend using it for larger projects as breaking changes and problems might occur. Warning: until version 1.0, nothing is guaranteed to be backwards compatible!

Features

  • Simple, fast binary serialization
  • Versioning using revision numbers
  • Error handling
  • Procedural macros to avoid boilerplate code
  • Versioning/size attributes using macros

Basic example

use binverse::{serialize::Serialize, streams::{Deserializer, Serializer}};
use binverse_derive::serializable;

fn main() {
    // Add #[serializable] for automatic Serialize/Deserialize
    // implementations and version handling.
    #[serializable]
    #[derive(Debug, PartialEq)]
    struct Example {
        a: i32,
        b: f32,
        c: String
    }

    let example = Example {
        a: -1253891,
        b: 44223.125,
        c: String::from("Hello binverse!")
    };

    // Create a serializer that writes into a Vec<u8>, could be replaced by
    // a file/network stream etc.
    let mut serializer = Serializer::new(Vec::new(), 0).unwrap();
    
    // Serialize the example struct into the serializer.
    example.serialize(&mut serializer).unwrap();

    // Get back the Vec<u8>.
    let data = serializer.finish();
    
    // The length of the data is pretty predictable:
    assert_eq!(data.len(), 
        4    // bytes for revision so the data can be read in future versions
        + 4  // a: i32
        + 4  // b: f32
        + 1  // length of the following string
             // (saved using VarInt, can be changed to a constant byte size)
        // the bytes of the string:
        + "Hello binverse!".len()
    );

    // Create a deserializer to recreate the Example instance using the data.
    let mut deserializer = Deserializer::new(data.as_slice()).unwrap();

    // Deserialize the struct. 
    let example_deserialized: Example = deserializer.deserialize().unwrap();
    
    // Both versions match
    assert_eq!(example, example_deserialized);
}

Dependencies

~1.5MB
~35K SLoC