wayk_proto/
serialization.rs1use crate::error::ProtoError;
2use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
3use std::io::{Cursor, Write};
4
5pub trait Encode {
9 fn encoded_len(&self) -> usize;
10
11 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError>
12 where
13 Self: Sized;
14
15 fn encode(&self) -> Result<Vec<u8>, ProtoError>
16 where
17 Self: Sized,
18 {
19 let mut buf = Cursor::new(Vec::new());
20 self.encode_into(&mut buf)?;
21 Ok(buf.into_inner())
22 }
23}
24
25sa::assert_obj_safe!(Encode);
26
27pub trait Decode<'dec>
69where
70 Self: Sized,
71{
72 fn decode_from(cursor: &mut Cursor<&'dec [u8]>) -> Result<Self, ProtoError>;
73
74 fn decode(bytes: &'dec [u8]) -> Result<Self, ProtoError> {
75 Self::decode_from(&mut Cursor::new(bytes))
76 }
77}
78
79impl Encode for u8 {
82 fn encoded_len(&self) -> usize {
83 std::mem::size_of::<Self>()
84 }
85
86 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
87 writer.write_u8(*self).map_err(ProtoError::from)
88 }
89}
90
91impl Decode<'_> for u8 {
92 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
93 cursor.read_u8().map_err(ProtoError::from)
94 }
95}
96
97impl Encode for u16 {
98 fn encoded_len(&self) -> usize {
99 std::mem::size_of::<Self>()
100 }
101
102 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
103 writer.write_u16::<LittleEndian>(*self).map_err(ProtoError::from)
104 }
105}
106
107impl Decode<'_> for u16 {
108 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
109 cursor.read_u16::<LittleEndian>().map_err(ProtoError::from)
110 }
111}
112
113impl Encode for u32 {
114 fn encoded_len(&self) -> usize {
115 std::mem::size_of::<Self>()
116 }
117
118 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
119 writer.write_u32::<LittleEndian>(*self).map_err(ProtoError::from)
120 }
121}
122
123impl Decode<'_> for u32 {
124 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
125 cursor.read_u32::<LittleEndian>().map_err(ProtoError::from)
126 }
127}
128
129impl Encode for u64 {
130 fn encoded_len(&self) -> usize {
131 std::mem::size_of::<Self>()
132 }
133
134 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
135 writer.write_u64::<LittleEndian>(*self).map_err(ProtoError::from)
136 }
137}
138
139impl Decode<'_> for u64 {
140 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
141 cursor.read_u64::<LittleEndian>().map_err(ProtoError::from)
142 }
143}
144
145impl Encode for u128 {
146 fn encoded_len(&self) -> usize {
147 std::mem::size_of::<Self>()
148 }
149
150 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
151 writer.write_u128::<LittleEndian>(*self).map_err(ProtoError::from)
152 }
153}
154
155impl Decode<'_> for u128 {
156 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
157 cursor.read_u128::<LittleEndian>().map_err(ProtoError::from)
158 }
159}
160
161impl Encode for i8 {
162 fn encoded_len(&self) -> usize {
163 std::mem::size_of::<Self>()
164 }
165
166 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
167 writer.write_i8(*self).map_err(ProtoError::from)
168 }
169}
170
171impl Decode<'_> for i8 {
172 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
173 cursor.read_i8().map_err(ProtoError::from)
174 }
175}
176
177impl Encode for i16 {
178 fn encoded_len(&self) -> usize {
179 std::mem::size_of::<Self>()
180 }
181
182 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
183 writer.write_i16::<LittleEndian>(*self).map_err(ProtoError::from)
184 }
185}
186
187impl Decode<'_> for i16 {
188 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
189 cursor.read_i16::<LittleEndian>().map_err(ProtoError::from)
190 }
191}
192
193impl Encode for i32 {
194 fn encoded_len(&self) -> usize {
195 std::mem::size_of::<Self>()
196 }
197
198 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
199 writer.write_i32::<LittleEndian>(*self).map_err(ProtoError::from)
200 }
201}
202
203impl Decode<'_> for i32 {
204 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
205 cursor.read_i32::<LittleEndian>().map_err(ProtoError::from)
206 }
207}
208
209impl Encode for i64 {
210 fn encoded_len(&self) -> usize {
211 std::mem::size_of::<Self>()
212 }
213
214 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
215 writer.write_i64::<LittleEndian>(*self).map_err(ProtoError::from)
216 }
217}
218
219impl Decode<'_> for i64 {
220 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
221 cursor.read_i64::<LittleEndian>().map_err(ProtoError::from)
222 }
223}
224
225impl Encode for i128 {
226 fn encoded_len(&self) -> usize {
227 std::mem::size_of::<Self>()
228 }
229
230 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
231 writer.write_i128::<LittleEndian>(*self).map_err(ProtoError::from)
232 }
233}
234
235impl Decode<'_> for i128 {
236 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
237 cursor.read_i128::<LittleEndian>().map_err(ProtoError::from)
238 }
239}
240
241impl Encode for [u32; 4] {
242 fn encoded_len(&self) -> usize {
243 std::mem::size_of::<Self>()
244 }
245
246 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
247 for element in self {
248 element.encode_into(writer)?;
249 }
250 Ok(())
251 }
252}
253
254impl Decode<'_> for [u32; 4] {
255 fn decode_from(cursor: &mut Cursor<&[u8]>) -> Result<Self, ProtoError> {
256 Ok([
257 cursor.read_u32::<LittleEndian>()?,
258 cursor.read_u32::<LittleEndian>()?,
259 cursor.read_u32::<LittleEndian>()?,
260 cursor.read_u32::<LittleEndian>()?,
261 ])
262 }
263}
264
265impl Encode for &[u8] {
266 fn encoded_len(&self) -> usize {
267 self.len()
268 }
269
270 fn encode_into<W: Write>(&self, writer: &mut W) -> Result<(), ProtoError> {
271 writer.write_all(self)?;
272 Ok(())
273 }
274}
275
276impl<'dec: 'a, 'a, T: 'a> Decode<'dec> for Box<T>
277where
278 T: Decode<'dec>,
279{
280 fn decode_from(cursor: &mut Cursor<&'dec [u8]>) -> Result<Self, ProtoError> {
281 T::decode_from(cursor).map(Box::new)
282 }
283}
284
285#[cfg(test)]
286mod tests {
287 use super::*;
288 use crate::container::Bytes8;
289
290 #[derive(Encode, Decode)]
291 struct StructDerive<'a> {
292 pub a: u8,
293 b: u8,
294 pub c: u16,
295 update_data: Bytes8<'a>,
296 }
297
298 const STRUCT_DERIVE_ENCODED: [u8; 8] = [0x10, 0x20, 0x30, 0x40, 0x03, 0x01, 0x02, 0x03];
299
300 #[test]
301 fn struct_derive_decode() {
302 let s = StructDerive::decode(&STRUCT_DERIVE_ENCODED).unwrap();
303 assert_eq!(s.a, 0x10);
304 assert_eq!(s.b, 0x20);
305 assert_eq!(s.c, 0x4030);
306 assert_eq!(s.update_data, &[0x01, 0x02, 0x03][0..]);
307 }
308
309 #[test]
310 fn struct_derive_encode() {
311 let s = StructDerive {
312 a: 0x10,
313 b: 0x20,
314 c: 0x4030,
315 update_data: Bytes8(&[0x01, 0x02, 0x03]),
316 };
317 assert_eq!(s.encode().unwrap(), STRUCT_DERIVE_ENCODED.to_vec());
318 }
319}