menhirkv 0.4.5

MenhirKV is yet another local KV store based on RocksDB.
Documentation
// Copyright (C) 2024 Christian Mauduit <ufoot@ufoot.org>

use crate::error::{Error, Result};
use bincode;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::io::Cursor;

const MAX_KEY_SIZE: usize = 16384;

pub(crate) fn deserialize_size<B>(buf: B) -> Result<usize>
where
    B: AsRef<[u8]>,
{
    let reader = Cursor::new(buf);
    match bincode::deserialize_from(reader) {
        Ok(v) => Ok(v),
        Err(e) => Err(Error::from(e)),
    }
}

pub(crate) fn serialize_size(size: usize) -> Result<Vec<u8>> {
    match bincode::serialize(&size) {
        Ok(v) => Ok(v),
        Err(e) => Err(Error::from(e)),
    }
}

pub(crate) fn deserialize_key<K, B>(buf: B) -> Result<K>
where
    K: DeserializeOwned,
    B: AsRef<[u8]>,
{
    let buf: &[u8] = buf.as_ref();
    let reader = Cursor::new(buf);
    match bincode::deserialize_from(reader) {
        Ok(k) => Ok(k),
        Err(e) => Err(Error::from(e)),
    }
}

pub(crate) fn serialize_key<K>(k: &K) -> Result<Vec<u8>>
where
    K: Serialize,
{
    match bincode::serialize(k) {
        Ok(buf) => {
            if buf.len() > MAX_KEY_SIZE {
                return Err(Error::invalid_data(&format!(
                    "key is {} bytes but max is {}",
                    buf.len(),
                    MAX_KEY_SIZE
                )));
            };
            Ok(buf)
        }
        Err(e) => Err(Error::from(e)),
    }
}

pub(crate) fn deserialize_value<V, B>(buf: B) -> Result<V>
where
    V: DeserializeOwned,
    B: AsRef<[u8]>,
{
    let buf: &[u8] = buf.as_ref();
    let reader = Cursor::new(buf);
    match bincode::deserialize_from(reader) {
        Ok(buf) => Ok(buf),
        Err(e) => Err(Error::from(e)),
    }
}

pub(crate) fn serialize_value<V>(v: &V) -> Result<Vec<u8>>
where
    V: Serialize,
{
    match bincode::serialize(v) {
        Ok(buf) => Ok(buf),
        Err(e) => Err(Error::from(e)),
    }
}

pub(crate) const MIN_KEY: [u8; 1] = [0; 1];
pub(crate) const MAX_KEY: [u8; MAX_KEY_SIZE] = [0xff; MAX_KEY_SIZE];

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_serialize_size() {
        let buf = serialize_size(42).unwrap();
        let size = deserialize_size(&buf).unwrap();
        assert_eq!(42, size);
    }

    #[test]
    fn test_serialize_key() {
        let key1 = 42u8;
        let buf = serialize_key(&key1).unwrap();
        let key2: u8 = deserialize_key(&buf).unwrap();
        assert_eq!(key1, key2);
    }
}