1use std::convert::Infallible;
4use std::error::Error;
5
6use std::io::{self, Read, Write};
7use std::marker::Sized;
8
9use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
10
11pub trait Encodable {
13 fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()>;
15 fn encoded_length(&self) -> u32;
17}
18
19impl<T: Encodable> Encodable for Option<T> {
29 fn encode<W: Write>(&self, writer: &mut W) -> io::Result<()> {
30 if let Some(this) = self {
31 this.encode(writer)?
32 }
33 Ok(())
34 }
35
36 fn encoded_length(&self) -> u32 {
37 self.as_ref().map_or(0, |x| x.encoded_length())
38 }
39}
40
41pub trait Decodable: Sized {
43 type Error: Error;
44 type Cond;
45
46 fn decode<R: Read>(reader: &mut R) -> Result<Self, Self::Error>
48 where
49 Self::Cond: Default,
50 {
51 Self::decode_with(reader, Default::default())
52 }
53
54 fn decode_with<R: Read>(reader: &mut R, cond: Self::Cond) -> Result<Self, Self::Error>;
56}
57
58impl<'a> Encodable for &'a str {
59 fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
60 assert!(self.as_bytes().len() <= u16::max_value() as usize);
61
62 writer
63 .write_u16::<BigEndian>(self.as_bytes().len() as u16)
64 .and_then(|_| writer.write_all(self.as_bytes()))
65 }
66
67 fn encoded_length(&self) -> u32 {
68 2 + self.as_bytes().len() as u32
69 }
70}
71
72impl<'a> Encodable for &'a [u8] {
73 fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
74 writer.write_all(self)
75 }
76
77 fn encoded_length(&self) -> u32 {
78 self.len() as u32
79 }
80}
81
82impl Encodable for String {
83 fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
84 (&self[..]).encode(writer)
85 }
86
87 fn encoded_length(&self) -> u32 {
88 (&self[..]).encoded_length()
89 }
90}
91
92impl Decodable for String {
93 type Error = io::Error;
94 type Cond = ();
95
96 fn decode_with<R: Read>(reader: &mut R, _rest: ()) -> Result<String, io::Error> {
97 let VarBytes(buf) = VarBytes::decode(reader)?;
98
99 String::from_utf8(buf).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
100 }
101}
102
103impl Encodable for Vec<u8> {
104 fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
105 (&self[..]).encode(writer)
106 }
107
108 fn encoded_length(&self) -> u32 {
109 (&self[..]).encoded_length()
110 }
111}
112
113impl Decodable for Vec<u8> {
114 type Error = io::Error;
115 type Cond = Option<u32>;
116
117 fn decode_with<R: Read>(reader: &mut R, length: Option<u32>) -> Result<Vec<u8>, io::Error> {
118 match length {
119 Some(length) => {
120 let mut buf = Vec::with_capacity(length as usize);
121 reader.take(length.into()).read_to_end(&mut buf)?;
122 Ok(buf)
123 }
124 None => {
125 let mut buf = Vec::new();
126 reader.read_to_end(&mut buf)?;
127 Ok(buf)
128 }
129 }
130 }
131}
132
133impl Encodable for () {
134 fn encode<W: Write>(&self, _: &mut W) -> Result<(), io::Error> {
135 Ok(())
136 }
137
138 fn encoded_length(&self) -> u32 {
139 0
140 }
141}
142
143impl Decodable for () {
144 type Error = Infallible;
145 type Cond = ();
146
147 fn decode_with<R: Read>(_: &mut R, _: ()) -> Result<(), Self::Error> {
148 Ok(())
149 }
150}
151
152#[derive(Debug, Eq, PartialEq, Clone)]
154pub struct VarBytes(pub Vec<u8>);
155
156impl Encodable for VarBytes {
157 fn encode<W: Write>(&self, writer: &mut W) -> Result<(), io::Error> {
158 assert!(self.0.len() <= u16::max_value() as usize);
159 let len = self.0.len() as u16;
160 writer.write_u16::<BigEndian>(len)?;
161 writer.write_all(&self.0)?;
162 Ok(())
163 }
164
165 fn encoded_length(&self) -> u32 {
166 2 + self.0.len() as u32
167 }
168}
169
170impl Decodable for VarBytes {
171 type Error = io::Error;
172 type Cond = ();
173 fn decode_with<R: Read>(reader: &mut R, _: ()) -> Result<VarBytes, io::Error> {
174 let length = reader.read_u16::<BigEndian>()?;
175 let mut buf = Vec::with_capacity(length as usize);
176 reader.take(length.into()).read_to_end(&mut buf)?;
177 Ok(VarBytes(buf))
178 }
179}
180
181#[cfg(test)]
182mod test {
183 use super::*;
184
185 use std::io::Cursor;
186
187 #[test]
188 fn varbyte_encode() {
189 let test_var = vec![0, 1, 2, 3, 4, 5];
190 let bytes = VarBytes(test_var);
191
192 assert_eq!(bytes.encoded_length() as usize, 2 + 6);
193
194 let mut buf = Vec::new();
195 bytes.encode(&mut buf).unwrap();
196
197 assert_eq!(&buf, &[0, 6, 0, 1, 2, 3, 4, 5]);
198
199 let mut reader = Cursor::new(buf);
200 let decoded = VarBytes::decode(&mut reader).unwrap();
201
202 assert_eq!(decoded, bytes);
203 }
204}