1use crate::Message;
2
3#[derive(Debug)]
5pub enum DecodeError {
6 Bincode(bincode::Error),
7 Json(serde_json::Error),
8}
9
10impl core::fmt::Display for DecodeError {
11 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
12 match self {
13 DecodeError::Bincode(e) => write!(f, "bincode decode error: {e}"),
14 DecodeError::Json(e) => write!(f, "json decode error: {e}"),
15 }
16 }
17}
18
19impl std::error::Error for DecodeError {
20 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
21 match self {
22 DecodeError::Bincode(e) => Some(e),
23 DecodeError::Json(e) => Some(e),
24 }
25 }
26}
27
28pub trait Codec {
30 fn encode(msg: &Message) -> Vec<u8>;
32
33 fn decode(buf: &[u8]) -> Result<Message, DecodeError>;
38}
39
40pub struct BincodeCodec;
42
43impl Codec for BincodeCodec {
44 fn encode(msg: &Message) -> Vec<u8> {
45 bincode::serialize(msg).expect("bincode serialization should succeed")
46 }
47
48 fn decode(buf: &[u8]) -> Result<Message, DecodeError> {
49 bincode::deserialize(buf).map_err(DecodeError::Bincode)
50 }
51}
52
53pub struct JsonCodec;
55
56impl Codec for JsonCodec {
57 fn encode(msg: &Message) -> Vec<u8> {
58 serde_json::to_vec(msg).expect("json serialization should succeed")
59 }
60
61 fn decode(buf: &[u8]) -> Result<Message, DecodeError> {
62 serde_json::from_slice(buf).map_err(DecodeError::Json)
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn bincode_roundtrip() {
72 let msg = Message::Ping { version: 1 };
73 let bytes = BincodeCodec::encode(&msg);
74 let decoded = BincodeCodec::decode(&bytes).unwrap();
75 assert!(matches!(decoded, Message::Ping { .. }));
76 }
77
78 #[test]
79 fn json_roundtrip() {
80 let msg = Message::Pong {
81 mac: "aa".into(),
82 version: 1,
83 };
84 let bytes = JsonCodec::encode(&msg);
85 let decoded = JsonCodec::decode(&bytes).unwrap();
86 assert!(matches!(decoded, Message::Pong { .. }));
87 }
88}