#bit #manager #derive #bit-store

macro bit_manager_derive

Derive macro for bit_manager crate

2 releases

Uses old Rust 2015

0.1.1 Nov 5, 2017
0.1.0 Nov 4, 2017

#245 in #bit

27 downloads per month
Used in extended-rational

MIT license

17KB
323 lines

Provides the derive macro for BitStore in the bit manager crate.

Usage

#[macro_use]
extern crate bit_manager_derive;
extern crate bit_manager;

use bit_manager::*;

#[derive(BitStore, PartialEq, Debug)]
struct Point {
    x: f64,
    y: f64,
}

After deriving, Point can be stored and read like this:

let point = Point {
    x: 6.28318531,
    y: 2.5,
};

let mut writer = BitWriter::new(Vec::new());
writer.write(&point)?;
let vec = writer.into_inner()?;

let mut reader = BitReader::new(&vec[..]);
assert_eq!(reader.read::<Point>()?, point);

Attributes

  • #[bit(align_enum="8")] uses integer multiples of the provided number for the amount of bits to store the indexes of enum variants, allowing future additions of items. Default number is zero. #[bit(align_enum)] uses a number of 8 bits. Max is 32 bits.
  • #[bit(verbose)] prints out the derived implementation and a record of which attributes were used.

Implemenation

Implementations for structs and enums are similar, but vary slightly.

Enums

Enum variants are stored by their index. The index is stored with the least amount of bits needed (by default) or with the least amount of bytes (using align_enum). Then, the fields of each variant are stored one at a time, like a struct. On reading, if the index doesn't match any variants, an Error::ConversionFailed is returned. Enums with no fields cannot be stored because they cannot be instantiated.

Structs

Structs store their contents one field at a time. Unit structs are a no-op. A failure to read an item will cause the reading to stop immediately and return the error.

The actual implementation of Point, when simplified, looks like this:

impl bit_manager::data::BitStore for Point {
    fn read_from<R: bit_manager::BitRead>(reader: &mut R) -> bit_manager::Result<Self> {
        Ok(
            Point {
                x: reader.read()?,
                y: reader.read()?,
            }
        )
    }
    fn write_to<W: bit_manager::BitWrite>(&self, writer: &mut W) -> bit_manager::Result<()> {
        writer.write(&self.x)?;
        writer.write(&self.y)
    }
}

Dependencies

~1.5MB
~41K SLoC