pub trait Coder: Clone + Send + Sync + 'static {
fn new() -> Self;
fn format_name(&self) -> &'static str;
fn encode_fmt1_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String>;
fn decode_fmt1_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String>;
fn encode_fmt1_list_to_buf<T: serde::ser::Serialize + IntoIterator>(&self, list: &T) -> Result<Vec<u8>, String>;
fn fmt1_list_len(&self, bytes: &[u8]) -> Result<usize, String>;
fn encode_fmt2_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String>;
fn decode_fmt2_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String>;
fn encode_fmt2_list_to_buf<T: serde::ser::Serialize + IntoIterator<Item=I>, I: Sized + Copy>(&self, list: &T) -> Result<Vec<u8>, String>;
fn fmt2_list_len(&self, bytes: &[u8]) -> Result<usize, String>;
}
#[cfg(feature = "bitcode")]
macro_rules! internal_coder {
() => { crate::BitcodeCoder };
}
#[cfg(all(feature = "bincode", not(feature = "bitcode")))]
pub(crate) static INTERNAL_CODER: std::sync::OnceLock<crate::BincodeCoder> = std::sync::OnceLock::new();
#[cfg(all(feature = "bincode", not(feature = "bitcode")))]
macro_rules! internal_coder {
() => { crate::encode_decode::INTERNAL_CODER.get_or_init(|| crate::BincodeCoder::new()) };
}
#[cfg(all(feature = "msgpack", not(feature = "bitcode"), not(feature = "bincode")))]
macro_rules! internal_coder {
() => { crate::MsgPackCoder };
}
pub(crate) use internal_coder;
#[cfg(feature = "bincode")]
pub(crate) mod bincode_interface {
use super::*;
use bincode::Options;
use bincode::config::*;
use crate::bincode_helpers::*;
#[derive(Clone)]
pub struct BincodeCoder {
varint_coder: WithOtherEndian<WithOtherIntEncoding<DefaultOptions, VarintEncoding>, LittleEndian>,
fixint_coder: WithOtherEndian<WithOtherIntEncoding<DefaultOptions, FixintEncoding>, LittleEndian>,
}
impl Coder for BincodeCoder {
fn new() -> Self {
Self {
varint_coder: bincode::DefaultOptions::new().with_varint_encoding().with_little_endian(),
fixint_coder: bincode::DefaultOptions::new().with_fixint_encoding().with_little_endian(),
}
}
fn format_name(&self) -> &'static str {
"bincode"
}
fn encode_fmt1_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String> {
self.varint_coder.serialize(obj).map_err(|e| format!("Encode error: {e}"))
}
fn decode_fmt1_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String> {
self.varint_coder.deserialize(bytes).map_err(|e| format!("Decode error: {e}"))
}
fn encode_fmt1_list_to_buf<T: serde::ser::Serialize + IntoIterator>(&self, list: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_to_buf(list)
}
fn fmt1_list_len(&self, bytes: &[u8]) -> Result<usize, String> {
let mut skip_bytes = 0;
let element_cnt = bincode_u64_le_varint(bytes, &mut skip_bytes);
Ok(element_cnt as usize)
}
fn encode_fmt2_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String> {
self.fixint_coder.serialize(obj).map_err(|e| format!("Encode error: {e}"))
}
fn decode_fmt2_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String> {
self.fixint_coder.deserialize(bytes).map_err(|e| format!("Decode error: {e}"))
}
fn encode_fmt2_list_to_buf<T: serde::ser::Serialize + IntoIterator<Item=I>, I: Sized + Copy>(&self, list: &T) -> Result<Vec<u8>, String> {
self.fixint_coder.serialize(list).map_err(|e| format!("Encode error: {e}"))
}
fn fmt2_list_len(&self, bytes: &[u8]) -> Result<usize, String> {
Ok(bincode_vec_fixint_len(bytes))
}
}
}
#[cfg(feature = "msgpack")]
pub(crate) mod msgpack_interface {
use super::*;
#[derive(Clone)]
pub struct MsgPackCoder;
impl Coder for MsgPackCoder {
fn new() -> Self {
Self
}
fn format_name(&self) -> &'static str {
"msgpack"
}
fn encode_fmt1_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String> {
rmp_serde::encode::to_vec(obj).map_err(|e| format!("Encode error: {e}"))
}
fn decode_fmt1_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String> {
rmp_serde::decode::from_slice(bytes).map_err(|e| format!("Decode error: {e}"))
}
fn encode_fmt1_list_to_buf<T: serde::ser::Serialize + IntoIterator>(&self, list: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_to_buf(list)
}
fn fmt1_list_len(&self, bytes: &[u8]) -> Result<usize, String> {
let element_cnt = rmp::decode::read_array_len(&mut &bytes[..]).map_err(|e| format!("Decode error: {e}"))?;
Ok(element_cnt as usize)
}
fn encode_fmt2_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_to_buf(obj)
}
fn decode_fmt2_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String> {
self.decode_fmt1_from_bytes(bytes)
}
fn encode_fmt2_list_to_buf<T: serde::ser::Serialize + IntoIterator<Item=I>, I: Sized + Copy>(&self, list: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_list_to_buf(list)
}
fn fmt2_list_len(&self, bytes: &[u8]) -> Result<usize, String> {
self.fmt1_list_len(bytes)
}
}
}
#[cfg(feature = "bitcode")]
pub(crate) mod bitcode_interface {
use super::*;
#[derive(Debug, Default, Clone, Copy)]
pub struct BitcodeCoder;
impl Coder for BitcodeCoder {
fn new() -> Self {
Self
}
fn format_name(&self) -> &'static str {
"bitcode v.0.6.0"
}
fn encode_fmt1_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String> {
bitcode::serialize(obj).map_err(|e| format!("Encode error: {e}"))
}
fn decode_fmt1_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String> {
bitcode::deserialize(bytes).map_err(|e| format!("Decode error: {e}"))
}
fn encode_fmt1_list_to_buf<T: serde::ser::Serialize + IntoIterator>(&self, list: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_to_buf(list)
}
fn fmt1_list_len(&self, bytes: &[u8]) -> Result<usize, String> {
fn invalid_length() -> String {
"invalid length".to_owned()
}
let first = *bytes.get(0).ok_or_else(invalid_length)?;
if first < 255 {
return Ok(first as usize);
}
match *bytes.get(1).ok_or_else(invalid_length)? {
4 => {
let len_chars = bytes.get(2..4).ok_or_else(invalid_length)?;
Ok(u16::from_le_bytes(len_chars.try_into().unwrap()) as usize)
}
2 => {
let len_chars = bytes.get(2..6).ok_or_else(invalid_length)?;
Ok(u32::from_le_bytes(len_chars.try_into().unwrap()) as usize)
}
0 => {
let len_chars = bytes.get(2..10).ok_or_else(invalid_length)?;
Ok(u64::from_le_bytes(len_chars.try_into().unwrap()) as usize)
}
_ => Err(invalid_length()),
}
}
fn encode_fmt2_to_buf<T: serde::ser::Serialize>(&self, obj: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_to_buf(obj)
}
fn decode_fmt2_from_bytes<'a, T: serde::de::Deserialize<'a>>(&self, bytes: &'a [u8]) -> Result<T, String> {
self.decode_fmt1_from_bytes(bytes)
}
fn encode_fmt2_list_to_buf<T: serde::ser::Serialize + IntoIterator<Item=I>, I: Sized + Copy>(&self, list: &T) -> Result<Vec<u8>, String> {
self.encode_fmt1_list_to_buf(list)
}
fn fmt2_list_len(&self, bytes: &[u8]) -> Result<usize, String> {
self.fmt1_list_len(bytes)
}
}
}
#[cfg(test)]
mod tests {
use crate::Coder;
#[test]
fn test_encode_len() {
let coder = crate::DefaultCoder::new();
let data = coder.encode_fmt1_list_to_buf(&"test".as_bytes()).unwrap();
let len = coder.fmt1_list_len(&data).unwrap();
assert_eq!(len , 4);
}
}