use crate::api::{ApiError, KeyEncodingId};
use crate::codec::bincode::{BeU64, RawBuf, Utf8};
use crate::codec::{KeyCodec as BufKeyCodec, ValueCodec as BufValueCodec};
pub trait KeyCodec: Sized {
const ENCODING: KeyEncodingId;
fn encode(&self) -> Vec<u8>;
fn decode(bytes: &[u8]) -> Result<Self, ApiError>;
}
pub trait ValueCodec: Sized {
fn encode(&self) -> Vec<u8>;
fn decode(bytes: &[u8]) -> Result<Self, ApiError>;
}
fn buf_encode_key<K, C: BufKeyCodec<K>>(key: &K) -> Vec<u8> {
let len = C::encoded_len(key);
let mut buf = vec![0u8; len];
C::encode_key(key, &mut buf).expect("encode into correctly-sized buffer");
buf
}
fn buf_decode_key<K, C: BufKeyCodec<K>>(bytes: &[u8]) -> Result<K, ApiError> {
C::decode_key(bytes).map_err(|e| ApiError::Decode(e.to_string()))
}
fn buf_encode_value<V, C: BufValueCodec<V>>(value: &V) -> Vec<u8> {
let len = C::encoded_len(value);
let mut buf = vec![0u8; len];
C::encode_value(value, &mut buf).expect("encode into correctly-sized buffer");
buf
}
fn buf_decode_value<V, C: BufValueCodec<V>>(bytes: &[u8]) -> Result<V, ApiError> {
C::decode_value(bytes).map_err(|e| ApiError::Decode(e.to_string()))
}
impl KeyCodec for u64 {
const ENCODING: KeyEncodingId = KeyEncodingId::BeU64;
fn encode(&self) -> Vec<u8> {
buf_encode_key::<u64, BeU64>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_key::<u64, BeU64>(bytes)
}
}
impl KeyCodec for i64 {
const ENCODING: KeyEncodingId = KeyEncodingId::BeI64;
fn encode(&self) -> Vec<u8> {
buf_encode_key::<i64, BeU64>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_key::<i64, BeU64>(bytes)
}
}
impl KeyCodec for String {
const ENCODING: KeyEncodingId = KeyEncodingId::Utf8;
fn encode(&self) -> Vec<u8> {
buf_encode_key::<String, Utf8>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_key::<String, Utf8>(bytes)
}
}
impl KeyCodec for Vec<u8> {
const ENCODING: KeyEncodingId = KeyEncodingId::RawBytes;
fn encode(&self) -> Vec<u8> {
buf_encode_key::<Vec<u8>, RawBuf>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_key::<Vec<u8>, RawBuf>(bytes)
}
}
impl ValueCodec for Vec<u8> {
fn encode(&self) -> Vec<u8> {
buf_encode_value::<Vec<u8>, RawBuf>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_value::<Vec<u8>, RawBuf>(bytes)
}
}
impl ValueCodec for String {
fn encode(&self) -> Vec<u8> {
buf_encode_value::<String, Utf8>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_value::<String, Utf8>(bytes)
}
}
impl ValueCodec for u64 {
fn encode(&self) -> Vec<u8> {
buf_encode_value::<u64, BeU64>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_value::<u64, BeU64>(bytes)
}
}
impl ValueCodec for i64 {
fn encode(&self) -> Vec<u8> {
buf_encode_value::<i64, BeU64>(self)
}
fn decode(bytes: &[u8]) -> Result<Self, ApiError> {
buf_decode_value::<i64, BeU64>(bytes)
}
}