protocol_message/
protocol_message.rs1use reliakit_codec::{
2 decode_from_slice_exact, encode_to_vec, CanonicalDecode, CanonicalEncode, CodecError,
3 CodecErrorKind, DecodeSource, EncodeSink,
4};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7struct ProtocolMessage {
8 id: u32,
9 kind: MessageKind,
10}
11
12#[derive(Debug, Clone, PartialEq, Eq)]
13enum MessageKind {
14 Ping,
15 Data(Vec<u8>),
16}
17
18impl CanonicalEncode for ProtocolMessage {
19 fn encode<W: EncodeSink + ?Sized>(&self, writer: &mut W) -> Result<(), CodecError> {
20 self.id.encode(writer)?;
21 self.kind.encode(writer)
22 }
23}
24
25impl CanonicalDecode for ProtocolMessage {
26 fn decode<R: DecodeSource + ?Sized>(reader: &mut R) -> Result<Self, CodecError> {
27 Ok(Self {
28 id: u32::decode(reader)?,
29 kind: MessageKind::decode(reader)?,
30 })
31 }
32}
33
34impl CanonicalEncode for MessageKind {
35 fn encode<W: EncodeSink + ?Sized>(&self, writer: &mut W) -> Result<(), CodecError> {
36 match self {
37 Self::Ping => 0u8.encode(writer),
38 Self::Data(bytes) => {
39 1u8.encode(writer)?;
40 bytes.encode(writer)
41 }
42 }
43 }
44}
45
46impl CanonicalDecode for MessageKind {
47 fn decode<R: DecodeSource + ?Sized>(reader: &mut R) -> Result<Self, CodecError> {
48 match u8::decode(reader)? {
49 0 => Ok(Self::Ping),
50 1 => Vec::<u8>::decode(reader).map(Self::Data),
51 _ => Err(CodecError::invalid_value(
52 "unknown MessageKind tag: expected 0x00 or 0x01",
53 )),
54 }
55 }
56}
57
58fn main() -> Result<(), CodecError> {
59 let message = ProtocolMessage {
60 id: 42,
61 kind: MessageKind::Data(vec![1, 2, 3]),
62 };
63
64 let encoded = encode_to_vec(&message)?;
65 assert_eq!(encoded, [42, 0, 0, 0, 1, 3, 0, 0, 0, 1, 2, 3]);
66 assert_eq!(
67 decode_from_slice_exact::<ProtocolMessage>(&encoded)?,
68 message
69 );
70
71 let err = decode_from_slice_exact::<MessageKind>(&[9]).unwrap_err();
72 assert_eq!(err.kind(), CodecErrorKind::InvalidValue);
73 assert!(err.message().contains("unknown MessageKind tag"));
74
75 Ok(())
76}