hyperion/servers/json/
codec.rs

1use bytes::BytesMut;
2use thiserror::Error;
3use tokio_util::codec::{Decoder, Encoder, LinesCodec};
4
5use crate::api::json::message;
6
7#[derive(Debug, Error)]
8pub enum JsonCodecError {
9    #[error("i/o error: {0}")]
10    Io(#[from] futures_io::Error),
11    #[error("lines codec error: {0}")]
12    Lines(#[from] tokio_util::codec::LinesCodecError),
13    #[error("invalid message: {0}")]
14    Serde(#[from] serde_json::Error),
15}
16
17/// JSON tokio codec
18pub struct JsonCodec {
19    /// Line parsing codec
20    lines: LinesCodec,
21}
22
23impl JsonCodec {
24    /// Create a new JsonCodec
25    pub fn new() -> Self {
26        Self {
27            lines: LinesCodec::new(),
28        }
29    }
30}
31
32impl Decoder for JsonCodec {
33    type Item = message::HyperionMessage;
34    type Error = JsonCodecError;
35
36    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
37        match self.lines.decode(src) {
38            Ok(lines_result) => Ok(match lines_result {
39                Some(ref line) => Some(serde_json::from_str(line)?),
40                None => None,
41            }),
42            Err(error) => Err(error.into()),
43        }
44    }
45}
46
47impl Encoder<message::HyperionResponse> for JsonCodec {
48    type Error = JsonCodecError;
49
50    fn encode(
51        &mut self,
52        item: message::HyperionResponse,
53        dst: &mut BytesMut,
54    ) -> Result<(), Self::Error> {
55        match serde_json::to_string(&item) {
56            Ok(encoded) => Ok(self.lines.encode(encoded, dst)?),
57            Err(encode_error) => Err(encode_error.into()),
58        }
59    }
60}