vecdb_derive

Crates.iovecdb_derive
lib.rsvecdb_derive
version0.6.1
created_at2025-08-09 10:19:34.480728+00
updated_at2026-01-20 23:14:08.120985+00
descriptionDerive for vecdb
homepagehttps://github.com/anydb-rs/anydb
repositoryhttps://github.com/anydb-rs/anydb
max_upload_size
id1787794
size26,789
(nym21)

documentation

README

vecdb_derive

Derive macros for vecdb to enable custom types in compressed and uncompressed vectors.

Provides two derive macros:

  • #[derive(Bytes)] - For use with BytesVec, LZ4Vec, ZstdVec
  • #[derive(Pco)] - For use with PcoVec (compressed numeric vectors)

Install

cargo add vecdb --features derive

Usage

Bytes Derive

Use #[derive(Bytes)] to enable custom wrapper types with uncompressed or general-purpose compressed vectors:

use vecdb::{Bytes, BytesVec, Database, Importable, Version};

#[derive(Debug, Clone, Copy, PartialEq, Bytes)]
struct UserId(u64);

#[derive(Debug, Clone, Copy, PartialEq, Bytes)]
struct Timestamp(i64);

fn main() -> vecdb::Result<()> {
    let db = Database::open("data")?;

    // Works with BytesVec
    let mut users: BytesVec<usize, UserId> =
        BytesVec::import(&db, "users", Version::TWO)?;
    users.push(UserId(12345));
    users.flush()?;

    // Also works with LZ4Vec and ZstdVec
    let mut timestamps: vecdb::LZ4Vec<usize, Timestamp> =
        vecdb::LZ4Vec::import(&db, "timestamps", Version::TWO)?;
    timestamps.push(Timestamp(1700000000));
    timestamps.flush()?;

    Ok(())
}

Requirements:

  • Must be a tuple struct with exactly one field
  • Inner type must implement Bytes
  • Works with generic types

Pco Derive

Use #[derive(Pco)] for numeric wrapper types to enable Pcodec compression:

use vecdb::{Pco, PcoVec, Database, Importable, Version};

#[derive(Debug, Clone, Copy, PartialEq, Pco)]
struct Price(f64);

#[derive(Debug, Clone, Copy, PartialEq, Pco)]
struct Quantity(u32);

fn main() -> vecdb::Result<()> {
    let db = Database::open("data")?;

    let mut prices: PcoVec<usize, Price> =
        PcoVec::import(&db, "prices", Version::TWO)?;
    prices.push(Price(99.99));
    prices.flush()?;

    Ok(())
}

Requirements:

  • Must be a tuple struct with exactly one field
  • Inner type must implement Pco (numeric types only: u16-u64, i16-i64, f32, f64)
  • The derive automatically implements both Bytes and Pco traits
  • Works with generic types

Generic Types

Both derives support generic type parameters:

use vecdb::{Bytes, Pco};

// Generic wrapper with Bytes
#[derive(Debug, Clone, Copy, PartialEq, Bytes)]
struct Wrapper<T>(T);

// Generic wrapper with Pco
#[derive(Debug, Clone, Copy, PartialEq, Pco)]
struct NumericWrapper<T>(T);

// Nested generics
#[derive(Debug, Clone, Copy, PartialEq, Pco)]
struct Container<T>(Wrapper<T>);

// Use with concrete types
let value = Wrapper(42u64);
let numeric = NumericWrapper(3.14f64);
let nested = Container(Wrapper(100u32));

The derives automatically add appropriate trait bounds (T: Bytes or T: Pco) to the generated implementations.

How It Works

Both derives implement traits by delegating to the inner type:

// #[derive(Bytes)] generates:
impl Bytes for Wrapper<T> where T: Bytes {
    fn to_bytes(&self) -> Vec<u8> {
        self.0.to_bytes()
    }
    fn from_bytes(bytes: &[u8]) -> Result<Self> {
        Ok(Self(T::from_bytes(bytes)?))
    }
}

// #[derive(Pco)] generates:
// - Bytes implementation (same as above)
// - Pco implementation with NumberType from inner type
// - TransparentPco marker trait

This allows wrapper types to have the same serialization and compression characteristics as their inner type.

Commit count: 256

cargo fmt