1use crate::{
2 codec::{GetSize, SizeHint},
3 datatypes::{
4 ShortTxId, Signature, Sv2DataType, U32AsRef, B016M, B0255, B032, B064K, U24, U256,
5 },
6 Error,
7};
8use alloc::vec::Vec;
9use std::convert::TryFrom;
10#[cfg(not(feature = "no_std"))]
11use std::io::{Cursor, Read};
12
13pub trait Decodable<'a>: Sized {
16 fn get_structure(data: &[u8]) -> Result<Vec<FieldMarker>, Error>;
17
18 fn from_decoded_fields(data: Vec<DecodableField<'a>>) -> Result<Self, Error>;
19
20 fn from_bytes(data: &'a mut [u8]) -> Result<Self, Error> {
21 let structure = Self::get_structure(data)?;
22 let mut fields = Vec::new();
23 let mut tail = data;
24
25 for field in structure {
26 let field_size = field.size_hint_(tail, 0)?;
27 if field_size > tail.len() {
28 return Err(Error::DecodableConversionError);
29 }
30 let (head, t) = tail.split_at_mut(field_size);
31 tail = t;
32 fields.push(field.decode(head)?);
33 }
34 Self::from_decoded_fields(fields)
35 }
36
37 #[cfg(not(feature = "no_std"))]
38 fn from_reader(reader: &mut impl Read) -> Result<Self, Error> {
39 let mut data = Vec::new();
40 reader.read_to_end(&mut data)?;
41
42 let structure = Self::get_structure(&data[..])?;
43
44 let mut fields = Vec::new();
45 let mut reader = Cursor::new(data);
46
47 for field in structure {
48 fields.push(field.from_reader(&mut reader)?);
49 }
50 Self::from_decoded_fields(fields)
51 }
52}
53
54#[derive(Debug, Clone, Copy)]
56pub enum PrimitiveMarker {
57 U8,
58 U16,
59 Bool,
60 U24,
61 U256,
62 ShortTxId,
63 Signature,
64 U32,
65 U32AsRef,
66 F32,
67 U64,
68 B032,
69 B0255,
70 B064K,
71 B016M,
72}
73
74#[derive(Debug, Clone)]
76pub enum FieldMarker {
77 Primitive(PrimitiveMarker),
78 Struct(Vec<FieldMarker>),
79}
80pub trait GetMarker {
81 fn get_marker() -> FieldMarker;
82}
83
84#[derive(Debug)]
86pub enum DecodablePrimitive<'a> {
87 U8(u8),
88 U16(u16),
89 Bool(bool),
90 U24(U24),
91 U256(U256<'a>),
92 ShortTxId(ShortTxId<'a>),
93 Signature(Signature<'a>),
94 U32(u32),
95 U32AsRef(U32AsRef<'a>),
96 F32(f32),
97 U64(u64),
98 B032(B032<'a>),
99 B0255(B0255<'a>),
100 B064K(B064K<'a>),
101 B016M(B016M<'a>),
102}
103
104#[derive(Debug)]
106pub enum DecodableField<'a> {
107 Primitive(DecodablePrimitive<'a>),
108 Struct(Vec<DecodableField<'a>>),
109}
110
111impl SizeHint for PrimitiveMarker {
112 fn size_hint(_data: &[u8], _offset: usize) -> Result<usize, Error> {
114 unimplemented!()
115 }
116
117 fn size_hint_(&self, data: &[u8], offset: usize) -> Result<usize, Error> {
118 match self {
119 Self::U8 => u8::size_hint(data, offset),
120 Self::U16 => u16::size_hint(data, offset),
121 Self::Bool => bool::size_hint(data, offset),
122 Self::U24 => U24::size_hint(data, offset),
123 Self::U256 => U256::size_hint(data, offset),
124 Self::ShortTxId => ShortTxId::size_hint(data, offset),
125 Self::Signature => Signature::size_hint(data, offset),
126 Self::U32 => u32::size_hint(data, offset),
127 Self::U32AsRef => U32AsRef::size_hint(data, offset),
128 Self::F32 => f32::size_hint(data, offset),
129 Self::U64 => u64::size_hint(data, offset),
130 Self::B032 => B032::size_hint(data, offset),
131 Self::B0255 => B0255::size_hint(data, offset),
132 Self::B064K => B064K::size_hint(data, offset),
133 Self::B016M => B016M::size_hint(data, offset),
134 }
135 }
136}
137
138impl SizeHint for FieldMarker {
139 fn size_hint(_data: &[u8], _offset: usize) -> Result<usize, Error> {
141 unimplemented!()
142 }
143
144 fn size_hint_(&self, data: &[u8], offset: usize) -> Result<usize, Error> {
145 match self {
146 Self::Primitive(p) => p.size_hint_(data, offset),
147 Self::Struct(ps) => {
148 let mut size = 0;
149 for p in ps {
150 size += p.size_hint_(data, offset + size)?;
151 }
152 Ok(size)
153 }
154 }
155 }
156}
157
158impl SizeHint for Vec<FieldMarker> {
159 fn size_hint(_data: &[u8], _offset: usize) -> Result<usize, Error> {
161 unimplemented!()
162 }
163
164 fn size_hint_(&self, data: &[u8], offset: usize) -> Result<usize, Error> {
165 let mut size = 0;
166 for field in self {
167 let field_size = field.size_hint_(data, offset + size)?;
168 size += field_size;
169 }
170 Ok(size)
171 }
172}
173
174impl From<PrimitiveMarker> for FieldMarker {
175 fn from(v: PrimitiveMarker) -> Self {
176 FieldMarker::Primitive(v)
177 }
178}
179
180impl TryFrom<Vec<FieldMarker>> for FieldMarker {
181 type Error = crate::Error;
182
183 fn try_from(mut v: Vec<FieldMarker>) -> Result<Self, crate::Error> {
184 match v.len() {
185 0 => Err(crate::Error::VoidFieldMarker),
189 1 => Ok(v.pop().unwrap()),
191 _ => Ok(FieldMarker::Struct(v)),
192 }
193 }
194}
195
196impl<'a> From<DecodableField<'a>> for Vec<DecodableField<'a>> {
197 fn from(v: DecodableField<'a>) -> Self {
198 match v {
199 DecodableField::Primitive(p) => vec![DecodableField::Primitive(p)],
200 DecodableField::Struct(ps) => ps,
201 }
202 }
203}
204
205impl PrimitiveMarker {
206 fn decode<'a>(&self, data: &'a mut [u8], offset: usize) -> DecodablePrimitive<'a> {
207 match self {
208 Self::U8 => DecodablePrimitive::U8(u8::from_bytes_unchecked(&mut data[offset..])),
209 Self::U16 => DecodablePrimitive::U16(u16::from_bytes_unchecked(&mut data[offset..])),
210 Self::Bool => DecodablePrimitive::Bool(bool::from_bytes_unchecked(&mut data[offset..])),
211 Self::U24 => DecodablePrimitive::U24(U24::from_bytes_unchecked(&mut data[offset..])),
212 Self::U256 => DecodablePrimitive::U256(U256::from_bytes_unchecked(&mut data[offset..])),
213 Self::ShortTxId => {
214 DecodablePrimitive::ShortTxId(ShortTxId::from_bytes_unchecked(&mut data[offset..]))
215 }
216 Self::Signature => {
217 DecodablePrimitive::Signature(Signature::from_bytes_unchecked(&mut data[offset..]))
218 }
219 Self::U32 => DecodablePrimitive::U32(u32::from_bytes_unchecked(&mut data[offset..])),
220 Self::U32AsRef => {
221 DecodablePrimitive::U32AsRef(U32AsRef::from_bytes_unchecked(&mut data[offset..]))
222 }
223 Self::F32 => DecodablePrimitive::F32(f32::from_bytes_unchecked(&mut data[offset..])),
224 Self::U64 => DecodablePrimitive::U64(u64::from_bytes_unchecked(&mut data[offset..])),
225 Self::B032 => DecodablePrimitive::B032(B032::from_bytes_unchecked(&mut data[offset..])),
226 Self::B0255 => {
227 DecodablePrimitive::B0255(B0255::from_bytes_unchecked(&mut data[offset..]))
228 }
229 Self::B064K => {
230 DecodablePrimitive::B064K(B064K::from_bytes_unchecked(&mut data[offset..]))
231 }
232 Self::B016M => {
233 DecodablePrimitive::B016M(B016M::from_bytes_unchecked(&mut data[offset..]))
234 }
235 }
236 }
237
238 #[allow(clippy::wrong_self_convention)]
239 #[cfg(not(feature = "no_std"))]
240 #[allow(clippy::wrong_self_convention)]
241 fn from_reader<'a>(&self, reader: &mut impl Read) -> Result<DecodablePrimitive<'a>, Error> {
242 match self {
243 Self::U8 => Ok(DecodablePrimitive::U8(u8::from_reader_(reader)?)),
244 Self::U16 => Ok(DecodablePrimitive::U16(u16::from_reader_(reader)?)),
245 Self::Bool => Ok(DecodablePrimitive::Bool(bool::from_reader_(reader)?)),
246 Self::U24 => Ok(DecodablePrimitive::U24(U24::from_reader_(reader)?)),
247 Self::U256 => Ok(DecodablePrimitive::U256(U256::from_reader_(reader)?)),
248 Self::ShortTxId => Ok(DecodablePrimitive::ShortTxId(ShortTxId::from_reader_(
249 reader,
250 )?)),
251 Self::Signature => Ok(DecodablePrimitive::Signature(Signature::from_reader_(
252 reader,
253 )?)),
254 Self::U32 => Ok(DecodablePrimitive::U32(u32::from_reader_(reader)?)),
255 Self::U32AsRef => Ok(DecodablePrimitive::U32AsRef(U32AsRef::from_reader_(
256 reader,
257 )?)),
258 Self::F32 => Ok(DecodablePrimitive::F32(f32::from_reader_(reader)?)),
259 Self::U64 => Ok(DecodablePrimitive::U64(u64::from_reader_(reader)?)),
260 Self::B032 => Ok(DecodablePrimitive::B032(B032::from_reader_(reader)?)),
261 Self::B0255 => Ok(DecodablePrimitive::B0255(B0255::from_reader_(reader)?)),
262 Self::B064K => Ok(DecodablePrimitive::B064K(B064K::from_reader_(reader)?)),
263 Self::B016M => Ok(DecodablePrimitive::B016M(B016M::from_reader_(reader)?)),
264 }
265 }
266}
267
268impl<'a> GetSize for DecodablePrimitive<'a> {
269 fn get_size(&self) -> usize {
270 match self {
271 DecodablePrimitive::U8(v) => v.get_size(),
272 DecodablePrimitive::U16(v) => v.get_size(),
273 DecodablePrimitive::Bool(v) => v.get_size(),
274 DecodablePrimitive::U24(v) => v.get_size(),
275 DecodablePrimitive::U256(v) => v.get_size(),
276 DecodablePrimitive::ShortTxId(v) => v.get_size(),
277 DecodablePrimitive::Signature(v) => v.get_size(),
278 DecodablePrimitive::U32(v) => v.get_size(),
279 DecodablePrimitive::U32AsRef(v) => v.get_size(),
280 DecodablePrimitive::F32(v) => v.get_size(),
281 DecodablePrimitive::U64(v) => v.get_size(),
282 DecodablePrimitive::B032(v) => v.get_size(),
283 DecodablePrimitive::B0255(v) => v.get_size(),
284 DecodablePrimitive::B064K(v) => v.get_size(),
285 DecodablePrimitive::B016M(v) => v.get_size(),
286 }
287 }
288}
289
290impl FieldMarker {
291 pub(crate) fn decode<'a>(&self, data: &'a mut [u8]) -> Result<DecodableField<'a>, Error> {
292 match self {
293 Self::Primitive(p) => Ok(DecodableField::Primitive(p.decode(data, 0))),
294 Self::Struct(ps) => {
295 let mut decodeds = Vec::new();
296 let mut tail = data;
297 for p in ps {
298 let field_size = p.size_hint_(tail, 0)?;
299 let (head, t) = tail.split_at_mut(field_size);
300 tail = t;
301 decodeds.push(p.decode(head)?);
302 }
303 Ok(DecodableField::Struct(decodeds))
304 }
305 }
306 }
307
308 #[allow(clippy::wrong_self_convention)]
309 #[cfg(not(feature = "no_std"))]
310 #[allow(clippy::wrong_self_convention)]
311 pub(crate) fn from_reader<'a>(
312 &self,
313 reader: &mut impl Read,
314 ) -> Result<DecodableField<'a>, Error> {
315 match self {
316 Self::Primitive(p) => Ok(DecodableField::Primitive(p.from_reader(reader)?)),
317 Self::Struct(ps) => {
318 let mut decodeds = Vec::new();
319 for p in ps {
320 decodeds.push(p.from_reader(reader)?);
321 }
322 Ok(DecodableField::Struct(decodeds))
323 }
324 }
325 }
326}