1use alloc::vec::Vec;
2use crate::codec_err::EncodeError;
3use crate::TypeInfo;
4
5pub trait Output {
7 fn write(&mut self, bytes: &[u8]);
9
10 fn push_byte(&mut self, byte: u8) {
12 self.write(&[byte]);
13 }
14}
15
16impl Output for Vec<u8> {
17 fn write(&mut self, bytes: &[u8]) {
18 self.extend_from_slice(bytes)
19 }
20}
21
22pub trait Encode: Sized {
27 #[doc(hidden)]
30 const TYPE_INFO: TypeInfo = TypeInfo::Unknown;
31
32 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
35 self.using_top_encoded(|buf| dest.write(buf))
36 }
37
38 fn top_encode(&self) -> Result<Vec<u8>, EncodeError> {
42 let mut dest = Vec::new();
43 self.using_top_encoded(|buf| dest.write(buf))?;
44 Ok(dest)
45 }
46
47 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
51 let mut dest: Vec<u8> = Vec::new();
53 self.dep_encode_to(&mut dest)?;
54 f(dest.as_slice());
55 Ok(())
56 }
57}
58
59impl Encode for () {
61 const TYPE_INFO: TypeInfo = TypeInfo::Unit;
62
63 fn dep_encode_to<O: Output>(&self, _dest: &mut O) -> Result<(), EncodeError> {
64 Ok(())
65 }
66
67 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
68 f(&[]);
69 Ok(())
70 }
71
72 fn top_encode(&self) -> Result<Vec<u8>, EncodeError> {
73 Ok(Vec::with_capacity(0))
74 }
75}
76
77impl Encode for u8 {
78 const TYPE_INFO: TypeInfo = TypeInfo::U8;
79
80 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
81 dest.write(&[*self as u8][..]);
82 Ok(())
83 }
84
85 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
86 if *self == 0u8 {
87 f(&[]);
88 } else {
89 f(&[*self][..]);
90 }
91 Ok(())
92 }
93}
94
95impl<T: Encode> Encode for &[T] {
96 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
97 using_encoded_number(self.len() as u64, 32, false, false, |buf| dest.write(buf));
99 match T::TYPE_INFO {
101 TypeInfo::U8 => {
102 let slice: &[u8] = unsafe { core::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
104 dest.write(slice);
105 },
106 _ => {
107 for x in *self {
108 x.dep_encode_to(dest)?;
109 }
110 }
111 }
112 Ok(())
113 }
114
115 #[inline]
116 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
117 match T::TYPE_INFO {
118 TypeInfo::U8 => {
119 let slice: &[u8] = unsafe { core::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
121 f(slice);
122 },
123 _ => {
124 let mut result: Vec<u8> = Vec::new();
125 for x in *self {
126 x.dep_encode_to(&mut result)?;
127 }
128 f(result.as_slice());
129 }
130 }
131 Ok(())
132 }
133}
134
135impl<T: Encode> Encode for &T {
136 #[inline]
137 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
138 (*self).dep_encode_to(dest)
139 }
140
141 #[inline]
142 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
143 (*self).using_top_encoded(f)
144 }
145}
146
147impl Encode for &str {
148 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
149 using_encoded_number(self.len() as u64, 32, false, false, |buf| dest.write(buf));
151 dest.write(self.as_bytes());
153 Ok(())
154 }
155
156 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
157 f(self.as_bytes());
158 Ok(())
159 }
160}
161
162impl<T: Encode> Encode for Vec<T> {
163 #[inline]
164 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
165 self.as_slice().dep_encode_to(dest)
166 }
167
168 #[inline]
169 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
170 self.as_slice().using_top_encoded(f)
171 }
172}
173
174
175pub fn using_encoded_number<F: FnOnce(&[u8])>(x: u64, size_in_bits: usize, signed: bool, mut compact: bool, f: F) {
180 let mut result = [0u8; 8];
181 let mut result_size = 0usize;
182 let negative =
183 compact && signed && x >> (size_in_bits - 1) & 1 == 1; let irrelevant_byte = if negative { 0xffu8 } else { 0x00u8 };
188 let mut bit_offset = size_in_bits as isize - 8;
189 while bit_offset >= 0 {
190 let byte = (x >> (bit_offset as usize) & 0xffu64) as u8;
192
193 if compact {
194 if byte != irrelevant_byte {
197 result[result_size] = byte;
198 result_size += 1;
199 compact = false;
200 }
201 } else {
202 result[result_size] = byte;
203 result_size += 1;
204 }
205
206 bit_offset -= 8;
207 }
208
209 f(&result[0..result_size])
210}
211
212macro_rules! encode_num {
213 ($num_type:ident, $size_in_bits:expr, $signed:expr, $type_info:expr) => {
214 impl Encode for $num_type {
215 const TYPE_INFO: TypeInfo = $type_info;
216
217 #[inline]
218 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
219 using_encoded_number(*self as u64, $size_in_bits, $signed, false, |buf| dest.write(buf));
220 Ok(())
221 }
222
223 #[inline]
224 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
225 using_encoded_number(*self as u64, $size_in_bits, $signed, true, f);
226 Ok(())
227 }
228 }
229 }
230}
231
232encode_num!{u64, 64, false, TypeInfo::U64}
233encode_num!{i64, 64, true, TypeInfo::I64}
234encode_num!{u32, 32, false, TypeInfo::U32}
235encode_num!{i32, 32, true, TypeInfo::I32}
236encode_num!{usize, 32, false, TypeInfo::U32}
237encode_num!{isize, 32, true, TypeInfo::I32}
238encode_num!{u16, 16, false, TypeInfo::U16}
239encode_num!{i16, 16, true, TypeInfo::I16}
240encode_num!{i8, 8, true, TypeInfo::I8}
241
242impl Encode for bool {
243 const TYPE_INFO: TypeInfo = TypeInfo::Bool;
244
245 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
246 dest.write(&[*self as u8][..]);
247 Ok(())
248 }
249
250 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
251 if *self {
252 f(&[1u8][..]);
253 } else {
254 f(&[]);
255 }
256 Ok(())
257 }
258}
259
260impl<T: Encode> Encode for Option<T> {
261 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
262 match self {
263 Some(v) => {
264 using_encoded_number(1u64, 8, false, false, |buf| dest.write(buf));
265 v.dep_encode_to(dest)
266 },
267 None => {
268 using_encoded_number(0u64, 8, false, false, |buf| dest.write(buf));
269 Ok(())
270 }
271 }
272 }
273
274 fn using_top_encoded<F: FnOnce(&[u8])>(&self, f: F) -> Result<(), EncodeError> {
277 match self {
278 Some(v) => {
279 let mut dest: Vec<u8> = Vec::new();
280 dest.push(1u8);
281 v.dep_encode_to(&mut dest)?;
282 f(dest.as_slice());
283 },
284 None => {
285 f(&[]);
286 }
287 }
288 Ok(())
289 }
290}
291
292macro_rules! tuple_impls {
293 ($(($($n:tt $name:ident)+))+) => {
294 $(
295 impl<$($name),+> Encode for ($($name,)+)
296 where
297 $($name: Encode,)+
298 {
299 #[inline]
300 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
301 $(
302 self.$n.dep_encode_to(dest)?;
303 )+
304 Ok(())
305 }
306 }
307 )+
308 }
309}
310
311tuple_impls! {
312 (0 T0)
313 (0 T0 1 T1)
314 (0 T0 1 T1 2 T2)
315 (0 T0 1 T1 2 T2 3 T3)
316 (0 T0 1 T1 2 T2 3 T3 4 T4)
317 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
318 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
319 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
320 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
321 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
322 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
323 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
324 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
325 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
326 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
327 (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
328}
329
330macro_rules! array_impls {
331 ($($n: tt,)+) => {
332 $(
333 impl<T: Encode> Encode for [T; $n] {
334 #[inline]
335 fn dep_encode_to<O: Output>(&self, dest: &mut O) -> Result<(), EncodeError> {
336 (&self[..]).using_top_encoded(|buf| dest.write(buf))
338 }
339 }
340 )+
341 }
342}
343
344array_impls!(
345 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
346 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
347 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
348 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
349 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
350 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
351 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
352 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
353 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156,
354 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172,
355 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188,
356 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204,
357 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
358 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236,
359 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
360 253, 254, 255, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768,
361);
362
363#[cfg(test)]
366mod tests {
367 use super::*;
368 use super::super::test_struct::*;
369 use core::fmt::Debug;
370
371 fn ser_ok<V>(element: V, expected_bytes: &[u8])
372 where
373 V: Encode + PartialEq + Debug + 'static,
374 {
375 V::using_top_encoded(&element, |bytes| {
376 assert_eq!(bytes, expected_bytes);
377 }).unwrap();
378
379 }
380
381 #[test]
382 fn test_top_compacted_numbers() {
383 ser_ok(5u8, &[5]);
385 ser_ok(5u16, &[5]);
386 ser_ok(5u32, &[5]);
387 ser_ok(5u64, &[5]);
388 ser_ok(5usize, &[5]);
389 ser_ok(5i8, &[5]);
391 ser_ok(5i16, &[5]);
392 ser_ok(5i32, &[5]);
393 ser_ok(5i64, &[5]);
394 ser_ok(5isize, &[5]);
395 ser_ok(-5i8, &[251]);
397 ser_ok(-5i16, &[251]);
398 ser_ok(-5i32, &[251]);
399 ser_ok(-5i64, &[251]);
400 ser_ok(-5isize, &[251]);
401 }
402
403 #[test]
404 fn test_top_compacted_bool() {
405 ser_ok(true, &[1]);
406 ser_ok(false, &[]);
407 }
408
409 #[test]
410 fn test_top_compacted_empty_bytes() {
411 let empty_byte_slice: &[u8] = &[];
412 ser_ok(empty_byte_slice, empty_byte_slice);
413 }
414
415 #[test]
416 fn test_top_compacted_bytes() {
417 ser_ok(&[1u8, 2u8, 3u8][..], &[1u8, 2u8, 3u8]);
418 }
419
420 #[test]
421 fn test_top_compacted_vec_u8() {
422 let some_vec = [1u8, 2u8, 3u8].to_vec();
423 ser_ok(some_vec, &[1u8, 2u8, 3u8]);
424 }
425
426 #[test]
427 fn test_top_compacted_vec_i32() {
428 let some_vec = [1i32, 2i32, 3i32].to_vec();
429 let expected: &[u8] = &[0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
430 ser_ok(some_vec, expected);
431 }
432
433 #[test]
434 fn test_struct() {
435 let test = Test {
436 int: 1,
437 seq: [5, 6].to_vec(),
438 another_byte: 7,
439 };
440
441 ser_ok(test, &[0, 1, 0, 0, 0, 2, 5, 6, 7]);
442 }
443
444 #[test]
445 fn test_tuple() {
446 ser_ok((7u32, -2i16), &[0, 0, 0, 7, 255, 254]);
447 }
448
449 #[test]
450 fn test_unit() {
451 ser_ok((), &[]);
452 }
453
454 #[test]
455 fn test_enum() {
456 let u = E::Unit;
457 let expected: &[u8] = &[0, 0, 0, 0];
458 ser_ok(u, expected);
459
460 let n = E::Newtype(1);
461 let expected: &[u8] = &[0, 0, 0, 1, 0, 0, 0, 1];
462 ser_ok(n, expected);
463
464 let t = E::Tuple(1, 2);
465 let expected: &[u8] = &[0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2 ];
466 ser_ok(t, expected);
467
468 let s = E::Struct { a: 1 };
469 let expected: &[u8] = &[0, 0, 0, 3, 0, 0, 0, 1];
470 ser_ok(s, expected);
471 }
472}