1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
//! The module contains the traits for encoding and decoding the types(a.k.a Codec).
//! It implements common codecs and encoders, but it is always possible to define own codecs.
use crate::kv_store::Value;
use std::{
borrow::Cow,
ops::Deref,
};
pub mod manual;
pub mod postcard;
pub mod primitive;
pub mod raw;
/// The trait is usually implemented by the encoder that stores serialized objects.
pub trait Encoder {
/// Returns the serialized object as a slice.
fn as_bytes(&self) -> Cow<[u8]>;
}
/// The trait encodes the type to the bytes and passes it to the `Encoder`,
/// which stores it and provides a reference to it. That allows gives more
/// flexibility and more performant encoding, allowing the use of slices and arrays
/// instead of vectors in some cases. Since the [`Encoder`] returns `Cow<[u8]>`,
/// it is always possible to take ownership of the serialized value.
pub trait Encode<T: ?Sized> {
/// The encoder type that stores serialized object.
type Encoder<'a>: Encoder
where
T: 'a;
/// Encodes the object to the bytes and passes it to the `Encoder`.
fn encode(t: &T) -> Self::Encoder<'_>;
/// Returns the serialized object as an [`Value`].
fn encode_as_value(t: &T) -> Value {
Value::new(Self::encode(t).as_bytes().into_owned())
}
}
/// The trait decodes the type from the bytes.
pub trait Decode<T> {
/// Decodes the type `T` from the bytes.
fn decode(bytes: &[u8]) -> anyhow::Result<T>;
/// Decodes the type `T` from the [`Value`].
fn decode_from_value(value: Value) -> anyhow::Result<T> {
Self::decode(value.deref())
}
}
impl<'a> Encoder for Cow<'a, [u8]> {
fn as_bytes(&self) -> Cow<[u8]> {
match self {
Cow::Borrowed(borrowed) => Cow::Borrowed(borrowed),
Cow::Owned(owned) => Cow::Borrowed(owned.as_ref()),
}
}
}
impl<const SIZE: usize> Encoder for [u8; SIZE] {
fn as_bytes(&self) -> Cow<[u8]> {
Cow::Borrowed(self.as_slice())
}
}