use std::io;
use compio_buf::{IoBuf, IoBufMut, Slice};
use serde::{Serialize, de::DeserializeOwned};
use thiserror::Error;
use crate::framed::codec::{Decoder, Encoder};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SerdeJsonCodec {
pretty: bool,
}
impl SerdeJsonCodec {
pub fn new() -> Self {
Self { pretty: false }
}
pub fn pretty() -> Self {
Self { pretty: true }
}
pub fn set_pretty(&mut self, pretty: bool) -> &mut Self {
self.pretty = pretty;
self
}
pub fn is_pretty(&self) -> bool {
self.pretty
}
}
impl Default for SerdeJsonCodec {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Error)]
pub enum SerdeJsonCodecError {
#[error("serde-json error: {0}")]
SerdeJsonError(serde_json::Error),
#[error("IO error: {0}")]
IoError(#[from] io::Error),
}
impl<T: Serialize, B: IoBufMut> Encoder<T, B> for SerdeJsonCodec {
type Error = SerdeJsonCodecError;
fn encode(&mut self, item: T, buf: &mut B) -> Result<(), Self::Error> {
let writer = buf.as_writer();
if self.pretty {
serde_json::to_writer_pretty(writer, &item)
} else {
serde_json::to_writer(writer, &item)
}
.map_err(SerdeJsonCodecError::SerdeJsonError)
}
}
impl<T: DeserializeOwned, B: IoBuf> Decoder<T, B> for SerdeJsonCodec {
type Error = SerdeJsonCodecError;
fn decode(&mut self, buf: &Slice<B>) -> Result<T, Self::Error> {
serde_json::from_slice(buf).map_err(SerdeJsonCodecError::SerdeJsonError)
}
}
#[test]
fn test_serde_json_codec() {
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
struct TestStruct {
id: u32,
name: String,
}
let mut codec = SerdeJsonCodec::new();
let item = TestStruct {
id: 114514,
name: "Test".to_string(),
};
let mut buffer = Vec::new();
codec.encode(item.clone(), &mut buffer).unwrap();
let slice = buffer.slice(..);
let decoded: TestStruct = codec.decode(&slice).unwrap();
assert_eq!(item, decoded);
}