use crate::error::*;
use rmp_serde;
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::io::{Cursor, Read};
#[derive(Debug, Clone)]
pub(crate) struct Node<K, V> {
pub(crate) link: Link<K>,
pub(crate) data: Data<K, V>,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct Data<K, V> {
pub(crate) key: K,
pub(crate) value: V,
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct DataRef<'a, K, V> {
pub(crate) key: &'a K,
pub(crate) value: &'a V,
}
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct Link<K> {
pub(crate) prev: K,
pub(crate) next: K,
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct LinkRef<'a, K> {
pub(crate) prev: &'a K,
pub(crate) next: &'a K,
}
#[derive(Debug, Clone, Default, Deserialize)]
pub(crate) struct Ptr<K> {
pub(crate) key: Option<K>,
}
#[derive(Debug, Clone, Default, Serialize)]
pub(crate) struct PtrRef<'a, K> {
pub(crate) key: Option<&'a K>,
}
const HEAD_KEY: &str = "HEAD";
const CAPACITY_KEY: &str = "CAPACITY";
const LEN_KEY: &str = "LEN";
const MAGIC_BYTE_LINK: u8 = 'N' as u8;
const MAGIC_BYTE_DATA: u8 = 'V' as u8;
const MAGIC_BYTE_PTR: u8 = 'P' as u8;
const MAGIC_BYTE_SIZE: u8 = 'S' as u8;
#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) enum KeyType {
Link,
Data,
Ptr,
Size,
}
impl<'a, K> std::convert::From<&'a Ptr<K>> for PtrRef<'a, K> {
fn from(ptr: &'a Ptr<K>) -> PtrRef<'a, K> {
match &ptr.key {
Some(key) => PtrRef { key: Some(&key) },
None => PtrRef { key: None },
}
}
}
impl<'a, K> std::convert::From<&'a Link<K>> for LinkRef<'a, K> {
fn from(link: &'a Link<K>) -> LinkRef<'a, K> {
LinkRef {
prev: &link.prev,
next: &link.next,
}
}
}
impl<'a, K, V> std::convert::From<&'a Data<K, V>> for DataRef<'a, K, V> {
fn from(data: &'a Data<K, V>) -> DataRef<'a, K, V> {
DataRef {
key: &data.key,
value: &data.value,
}
}
}
impl std::convert::From<KeyType> for u8 {
fn from(t: KeyType) -> u8 {
match t {
KeyType::Link => MAGIC_BYTE_LINK,
KeyType::Data => MAGIC_BYTE_DATA,
KeyType::Ptr => MAGIC_BYTE_PTR,
KeyType::Size => MAGIC_BYTE_SIZE,
}
}
}
impl std::convert::TryFrom<u8> for KeyType {
type Error = Error;
fn try_from(b: u8) -> Result<KeyType> {
match b {
MAGIC_BYTE_LINK => Ok(KeyType::Link),
MAGIC_BYTE_DATA => Ok(KeyType::Data),
MAGIC_BYTE_PTR => Ok(KeyType::Ptr),
MAGIC_BYTE_SIZE => Ok(KeyType::Size),
u => Err(Error::invalid_data(&format!("unknown magic byte {}", u))),
}
}
}
pub(crate) fn deserialize_size<B>(buf: B) -> Result<usize>
where
B: AsRef<[u8]>,
{
let reader = Cursor::new(buf);
match rmp_serde::from_read(reader) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn serialize_size(size: usize) -> Result<Vec<u8>> {
match rmp_serde::to_vec(&size) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn deserialize_ptr<K, B>(buf: B) -> Result<Ptr<K>>
where
B: AsRef<[u8]>,
K: DeserializeOwned,
{
let reader = Cursor::new(buf);
match rmp_serde::from_read(reader) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn serialize_ptr_ref<K>(ptr: &PtrRef<K>) -> Result<Vec<u8>>
where
K: Serialize,
{
match rmp_serde::to_vec(ptr) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn deserialize_link<K, B>(buf: B) -> Result<Link<K>>
where
B: AsRef<[u8]>,
K: DeserializeOwned,
{
let reader = Cursor::new(buf);
match rmp_serde::from_read(reader) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn serialize_link_ref<K>(link: &LinkRef<K>) -> Result<Vec<u8>>
where
K: Serialize,
{
match rmp_serde::to_vec(link) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn deserialize_key<K, B>(buf: B) -> Result<(Option<K>, KeyType)>
where
K: DeserializeOwned,
B: AsRef<[u8]>,
{
let buf: &[u8] = buf.as_ref();
let l = buf.len();
match l {
0 => Err(Error::report_bug("bad key, no data")),
_ => {
let mut reader = Cursor::new(buf);
let mut header: [u8; 1] = [0; 1];
match reader.read_exact(&mut header) {
Ok(_) => (),
Err(e) => {
return Err(Error::report_bug(&format!(
"unable to get key type header: {}",
e
)))
}
};
let kt = KeyType::try_from(buf[0])?;
match kt {
KeyType::Ptr | KeyType::Size => Ok((None, kt)),
KeyType::Data | KeyType::Link => match rmp_serde::from_read(reader) {
Ok(v) => Ok((v, kt)),
Err(e) => Err(Error::from(e)),
},
}
}
}
}
fn serialize_key<K>(k: &K, t: KeyType) -> Result<Vec<u8>>
where
K: Serialize,
{
match rmp_serde::to_vec(k) {
Ok(mut v) => {
let magic_byte: u8 = u8::from(t);
let mut ret: Vec<u8> = vec![magic_byte];
ret.append(&mut v);
Ok(ret)
}
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn serialize_key_size<S>(s: &S) -> Result<Vec<u8>>
where
S: Serialize,
{
serialize_key(s, KeyType::Size)
}
pub(crate) fn serialize_key_capacity() -> Result<Vec<u8>> {
serialize_key_size(&CAPACITY_KEY)
}
pub(crate) fn serialize_key_len() -> Result<Vec<u8>> {
serialize_key_size(&LEN_KEY)
}
pub(crate) fn serialize_key_ptr<S>(s: &S) -> Result<Vec<u8>>
where
S: Serialize,
{
serialize_key(s, KeyType::Ptr)
}
pub(crate) fn serialize_key_head() -> Result<Vec<u8>> {
serialize_key_ptr(&HEAD_KEY)
}
pub(crate) fn serialize_key_link<K>(k: &K) -> Result<Vec<u8>>
where
K: Serialize,
{
serialize_key(k, KeyType::Link)
}
pub(crate) fn serialize_key_data<K>(k: &K) -> Result<Vec<u8>>
where
K: Serialize,
{
serialize_key(k, KeyType::Data)
}
pub(crate) fn deserialize_data<K, V, B>(b: B) -> Result<Data<K, V>>
where
K: DeserializeOwned,
V: DeserializeOwned,
B: AsRef<[u8]>,
{
let reader = Cursor::new(b);
match rmp_serde::from_read(reader) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn serialize_data_ref<K, V>(data: &DataRef<K, V>) -> Result<Vec<u8>>
where
K: Serialize,
V: Serialize,
{
match rmp_serde::to_vec(data) {
Ok(v) => Ok(v),
Err(e) => Err(Error::from(e)),
}
}
pub(crate) fn serialize_kv_ptr<S, K>(s: &S, key: Option<&K>) -> Result<(Vec<u8>, Vec<u8>)>
where
S: Serialize,
K: Serialize,
{
let buf_p = serialize_key_ptr(s)?;
let buf_k = serialize_ptr_ref(&PtrRef { key })?;
Ok((buf_p, buf_k))
}
pub(crate) fn serialize_kv_head<K>(key: Option<&K>) -> Result<(Vec<u8>, Vec<u8>)>
where
K: Serialize,
{
serialize_kv_ptr(&HEAD_KEY, key)
}
pub(crate) fn serialize_kv_size<S>(s: &S, size: usize) -> Result<(Vec<u8>, Vec<u8>)>
where
S: Serialize,
{
let buf_p = serialize_key_size(s)?;
let buf_k = serialize_size(size)?;
Ok((buf_p, buf_k))
}
pub(crate) fn serialize_kv_capacity(capacity: usize) -> Result<(Vec<u8>, Vec<u8>)> {
serialize_kv_size(&CAPACITY_KEY, capacity)
}
pub(crate) fn serialize_kv_len(len: usize) -> Result<(Vec<u8>, Vec<u8>)> {
serialize_kv_size(&LEN_KEY, len)
}
pub(crate) fn serialize_kv_link<K>(key: &K, prev: &K, next: &K) -> Result<(Vec<u8>, Vec<u8>)>
where
K: Serialize,
{
let buf_k = serialize_key_link(key)?;
let buf_n = serialize_link_ref(&LinkRef { prev, next })?;
Ok((buf_k, buf_n))
}
pub(crate) fn serialize_kv_data<K, V>(key: &K, value: &V) -> Result<(Vec<u8>, Vec<u8>)>
where
K: Serialize,
V: Serialize,
{
let buf_k = serialize_key_data(key)?;
let buf_v = serialize_data_ref(&DataRef { key, value })?;
Ok((buf_k, buf_v))
}
#[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_ptr() {
let ptr1: Ptr<String> = Ptr {
key: Some("x".to_string()),
};
let ptr_ref = PtrRef::from(&ptr1);
let buf = serialize_ptr_ref(&ptr_ref).unwrap();
let ptr2: Ptr<String> = deserialize_ptr(&buf).unwrap();
assert_eq!(ptr1.key, ptr2.key);
}
#[test]
fn test_serialize_link() {
let link1: Link<String> = Link {
prev: "abc".to_string(),
next: "def".to_string(),
};
let link_ref = LinkRef::from(&link1);
let buf = serialize_link_ref(&link_ref).unwrap();
let link2: Link<String> = deserialize_link(&buf).unwrap();
assert_eq!(link1.prev, link2.prev);
assert_eq!(link1.next, link2.next);
}
#[test]
fn test_serialize_key() {
let key: usize = 42;
let buf_size = serialize_key_size(&key).unwrap();
let buf_ptr = serialize_key_ptr(&key).unwrap();
let buf_link = serialize_key_link(&key).unwrap();
let buf_data = serialize_key_data(&key).unwrap();
assert_ne!(buf_size, buf_ptr);
assert_ne!(buf_ptr, buf_link);
assert_ne!(buf_link, buf_data);
assert_ne!(buf_data, buf_size);
let key_size: (Option<String>, KeyType) = deserialize_key(&buf_size).unwrap();
let key_ptr: (Option<String>, KeyType) = deserialize_key(&buf_ptr).unwrap();
let key_link: (Option<usize>, KeyType) = deserialize_key(&buf_link).unwrap();
let key_data: (Option<usize>, KeyType) = deserialize_key(&buf_data).unwrap();
assert_eq!(None, key_size.0);
assert_eq!(None, key_ptr.0);
assert_eq!(Some(key), key_link.0);
assert_eq!(Some(key), key_data.0);
assert_eq!(KeyType::Size, key_size.1);
assert_eq!(KeyType::Ptr, key_ptr.1);
assert_eq!(KeyType::Link, key_link.1);
assert_eq!(KeyType::Data, key_data.1);
}
#[test]
fn test_serialize_data() {
let data1: Data<usize, String> = Data {
key: 42,
value: "def".to_string(),
};
let data_ref = DataRef::from(&data1);
let buf = serialize_data_ref(&data_ref).unwrap();
let data2: Data<usize, String> = deserialize_data(&buf).unwrap();
assert_eq!(data1.key, data2.key);
assert_eq!(data1.value, data2.value);
}
}