use serde::{de::DeserializeOwned, Serialize};
use std::fmt;
pub trait DataConverter: Send + Sync {
fn encode<T: Serialize>(&self, value: &T) -> Result<Vec<u8>, EncodingError>;
fn decode<T: DeserializeOwned>(&self, data: &[u8]) -> Result<T, EncodingError>;
}
pub struct JsonDataConverter;
impl JsonDataConverter {
pub fn new() -> Self {
Self
}
}
impl Default for JsonDataConverter {
fn default() -> Self {
Self::new()
}
}
impl DataConverter for JsonDataConverter {
fn encode<T: Serialize>(&self, value: &T) -> Result<Vec<u8>, EncodingError> {
serde_json::to_vec(value).map_err(|e| EncodingError::Serialization(e.to_string()))
}
fn decode<T: DeserializeOwned>(&self, data: &[u8]) -> Result<T, EncodingError> {
serde_json::from_slice(data).map_err(|e| EncodingError::Deserialization(e.to_string()))
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum EncodingError {
Serialization(String),
Deserialization(String),
UnsupportedEncoding(String),
}
impl fmt::Display for EncodingError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EncodingError::Serialization(msg) => write!(f, "Serialization error: {}", msg),
EncodingError::Deserialization(msg) => write!(f, "Deserialization error: {}", msg),
EncodingError::UnsupportedEncoding(enc) => {
write!(f, "Unsupported encoding: {}", enc)
}
}
}
}
impl std::error::Error for EncodingError {}
#[derive(Debug, Clone, PartialEq)]
pub struct EncodedValue {
data: Vec<u8>,
encoding: Encoding,
}
impl EncodedValue {
pub fn new(data: Vec<u8>) -> Self {
Self {
data,
encoding: Encoding::Json,
}
}
pub fn with_encoding(data: Vec<u8>, encoding: Encoding) -> Self {
Self { data, encoding }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
pub fn encoding(&self) -> Encoding {
self.encoding
}
pub fn decode<T: DeserializeOwned>(&self) -> Result<T, EncodingError> {
match self.encoding {
Encoding::Json => serde_json::from_slice(&self.data)
.map_err(|e| EncodingError::Deserialization(e.to_string())),
Encoding::Raw => Err(EncodingError::UnsupportedEncoding(
"Cannot decode raw bytes".to_string(),
)),
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Encoding {
Json,
Raw,
}
#[derive(Debug, Clone, PartialEq)]
pub struct EncodedValues {
data: Vec<u8>,
}
impl EncodedValues {
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
pub fn as_bytes(&self) -> &[u8] {
&self.data
}
pub fn decode<T: DeserializeOwned>(&self) -> Result<T, EncodingError> {
serde_json::from_slice(&self.data)
.map_err(|e| EncodingError::Deserialization(e.to_string()))
}
}
pub fn encode<T: Serialize>(value: &T) -> Result<Vec<u8>, EncodingError> {
JsonDataConverter::new().encode(value)
}
pub fn decode<T: DeserializeOwned>(data: &[u8]) -> Result<T, EncodingError> {
JsonDataConverter::new().decode(data)
}
#[cfg(test)]
mod tests {
use super::*;
use serde::Deserialize;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct TestStruct {
name: String,
value: i32,
}
#[test]
fn test_json_encode_decode() {
let converter = JsonDataConverter::new();
let original = TestStruct {
name: "test".to_string(),
value: 42,
};
let encoded = converter.encode(&original).unwrap();
let decoded: TestStruct = converter.decode(&encoded).unwrap();
assert_eq!(original, decoded);
}
#[test]
fn test_encoded_value() {
let original = TestStruct {
name: "test".to_string(),
value: 42,
};
let data = encode(&original).unwrap();
let encoded = EncodedValue::new(data);
let decoded: TestStruct = encoded.decode().unwrap();
assert_eq!(original, decoded);
}
}