1use crate::{string, vec};
2
3use crate::{Layout, ReaderExt, Result, reader};
4
5pub trait Decode: Sized + Layout {
6 fn decode(buffer: &[u8]) -> Result<Self>;
7}
8impl Decode for bool {
9 fn decode(r: &[u8]) -> Result<Self> {
10 let [v] = r.read_const::<1>();
11 Ok(v != 0)
12 }
13}
14
15impl Decode for i8 {
16 fn decode(r: &[u8]) -> Result<Self> {
17 Ok(i8::from_le_bytes(r.read_const()))
18 }
19}
20impl Decode for i16 {
21 fn decode(r: &[u8]) -> Result<Self> {
22 Ok(i16::from_le_bytes(r.read_const()))
23 }
24}
25impl Decode for i32 {
26 fn decode(r: &[u8]) -> Result<Self> {
27 Ok(i32::from_le_bytes(r.read_const()))
28 }
29}
30impl Decode for i64 {
31 fn decode(r: &[u8]) -> Result<Self> {
32 Ok(i64::from_le_bytes(r.read_const()))
33 }
34}
35impl Decode for u8 {
36 fn decode(r: &[u8]) -> Result<Self> {
37 Ok(u8::from_le_bytes(r.read_const()))
38 }
39}
40impl Decode for u16 {
41 fn decode(r: &[u8]) -> Result<Self> {
42 Ok(u16::from_le_bytes(r.read_const()))
43 }
44}
45impl Decode for u32 {
46 fn decode(r: &[u8]) -> Result<Self> {
47 Ok(u32::from_le_bytes(r.read_const()))
48 }
49}
50impl Decode for u64 {
51 fn decode(r: &[u8]) -> Result<Self> {
52 Ok(u64::from_le_bytes(r.read_const()))
53 }
54}
55impl Decode for f32 {
56 fn decode(r: &[u8]) -> Result<Self> {
57 Ok(f32::from_le_bytes(r.read_const()))
58 }
59}
60impl Decode for f64 {
61 fn decode(r: &[u8]) -> Result<Self> {
62 Ok(f64::from_le_bytes(r.read_const()))
63 }
64}
65
66impl Decode for string::String {
67 fn decode(r: &[u8]) -> Result<Self> {
68 let (offset, len) = reader::ArrayReader::<&[u8]>::read_head(r);
69
70 let buf = r.skip(offset).read_n(len).to_vec();
71 Ok(string::String::from_utf8(buf).unwrap())
72 }
73}
74impl<E: Decode> Decode for vec::Vec<E> {
75 fn decode(r: &[u8]) -> Result<Self> {
76 let (offset, len) = reader::ArrayReader::<&[u8]>::read_head(r);
77 let mut buf = r.skip(offset);
78
79 let mut out = vec::Vec::with_capacity(len);
80 let item_head_bytes = E::head_size().div_ceil(8);
81 for _ in 0..len {
82 out.push(E::decode(buf)?);
83 buf = buf.skip(item_head_bytes);
84 }
85 Ok(out)
86 }
87}
88impl<E: Decode> Decode for Option<E> {
89 fn decode(buf: &[u8]) -> Result<Self> {
90 let [tag] = buf.read_const::<1>();
91 if tag == 0 {
92 Ok(None)
93 } else {
94 let buf = buf.skip(1);
95 let inner_head_size = E::head_size();
96 let has_ptr = inner_head_size > 32;
97
98 Ok(Some(if has_ptr {
99 let offset = u32::from_le_bytes(buf.read_const::<4>()) as usize;
100 E::decode(buf.skip(offset))?
101 } else {
102 E::decode(buf)?
103 }))
104 }
105 }
106}
107impl Decode for () {
108 fn decode(_buf: &[u8]) -> Result<Self> {
109 Ok(())
110 }
111}
112
113pub fn decode_enum_head(mut data: &[u8], tag_bytes: u8, has_ptr: bool) -> (u64, &[u8]) {
114 use crate::ReaderExt;
115 use bytes::Buf;
116
117 let mut tag = vec![0; 8];
118 data.copy_to_slice(&mut tag[0..tag_bytes as usize]);
119 let tag = u64::from_le_bytes(tag.try_into().unwrap()) as u64;
120
121 if has_ptr {
122 let offset = u32::from_le_bytes(data.read_const::<4>());
124 data = data.skip(offset as usize);
125 } else {
126 }
128
129 (tag, data)
130}