hyperion/servers/boblight/
codec.rs

1use bytes::BytesMut;
2use thiserror::Error;
3use tokio_util::codec::{Decoder, Encoder, LinesCodec};
4
5use crate::api::boblight::message;
6
7#[derive(Debug, Error)]
8pub enum BoblightCodecError {
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    Message(#[from] message::DecodeError),
15}
16
17/// JSON tokio codec
18pub struct BoblightCodec {
19    /// Line parsing codec
20    lines: LinesCodec,
21}
22
23impl BoblightCodec {
24    /// Create a new BoblightCodec
25    pub fn new() -> Self {
26        Self {
27            lines: LinesCodec::new(),
28        }
29    }
30}
31
32impl Decoder for BoblightCodec {
33    type Item = message::BoblightRequest;
34    type Error = BoblightCodecError;
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(line.parse()?),
40                None => None,
41            }),
42            Err(error) => Err(error.into()),
43        }
44    }
45}
46
47impl Encoder<message::BoblightResponse> for BoblightCodec {
48    type Error = BoblightCodecError;
49
50    fn encode(
51        &mut self,
52        item: message::BoblightResponse,
53        dst: &mut BytesMut,
54    ) -> Result<(), Self::Error> {
55        Ok(self.lines.encode(item.to_string(), dst)?)
56    }
57}