bluerobotics_ping/
codec.rs1use crate::{decoder::Decoder as PingDecoder, error::PingError, message::ProtocolMessage};
2use bytes::{Buf, BytesMut};
3use tokio_util::codec::{Decoder, Encoder};
4use tracing::debug;
5
6pub struct PingCodec {
7 decoder: PingDecoder,
8}
9
10impl PingCodec {
11 pub fn new() -> Self {
12 PingCodec {
13 decoder: PingDecoder::new(),
14 }
15 }
16}
17
18impl Decoder for PingCodec {
19 type Item = ProtocolMessage;
20 type Error = PingError;
21
22 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
23 let decoder = &mut self.decoder;
24 let mut consumed = 0;
25
26 loop {
27 let Some(byte) = src.get(consumed) else {
28 return Ok(None);
29 };
30
31 let state = decoder.parse_byte(*byte);
32 debug!("Decoder state: {:?}", state);
33 match state {
34 crate::decoder::DecoderResult::InProgress(_) => {
35 consumed += 1;
36 if consumed == src.len() {
37 src.advance(consumed)
38 }
39 }
40 crate::decoder::DecoderResult::Success(msg) => {
41 src.advance(consumed + 1);
42 return Ok(Some(msg));
43 }
44 crate::decoder::DecoderResult::Error(e) => {
45 src.advance(consumed + 1);
46 return Err(PingError::ParseError(e));
47 }
48 }
49 }
50 }
51}
52
53impl Encoder<ProtocolMessage> for PingCodec {
54 type Error = PingError;
55
56 fn encode(&mut self, item: ProtocolMessage, dst: &mut BytesMut) -> Result<(), Self::Error> {
57 dst.extend_from_slice(&item.serialized());
58 Ok(())
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use crate::common;
66
67 #[test]
68 fn test_ping_codec() {
69 let mut codec = PingCodec::new();
70
71 let buffer: Vec<u8> = vec![
73 0x42, 0x52, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa1, 0x00, ];
79 let mut bytes_mut = BytesMut::new();
80 bytes_mut.extend_from_slice(&buffer);
81
82 let request =
84 common::Messages::GeneralRequest(common::GeneralRequestStruct { requested_id: 5 });
85 let mut package = crate::message::ProtocolMessage::new();
86 package.set_message(&request);
87
88 let decoded_message = codec.decode(&mut bytes_mut).unwrap().unwrap();
90
91 assert_eq!(decoded_message, package);
93
94 let wrong_buffer: Vec<u8> = vec![
96 0x42, 0x52, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa1, 0x01, ];
102 let mut wrong_bytes_mut = BytesMut::new();
103 wrong_bytes_mut.extend_from_slice(&wrong_buffer);
104
105 let decoded_message = codec.decode(&mut wrong_bytes_mut);
107
108 assert!(matches!(decoded_message, Err(PingError::ParseError(_))));
109
110 let mut encoded = BytesMut::new();
111 codec.encode(package.clone(), &mut encoded).unwrap();
112
113 assert_eq!(encoded.to_vec(), buffer);
115 }
116}