1use crate::{
2 codec::{GetSize, SizeHint},
3 datatypes::{Signature, Sv2DataType, U32AsRef, B016M, B0255, B032, B064K, U24, U256},
4 Error,
5};
6use alloc::vec::Vec;
7use core::convert::TryFrom;
8#[cfg(not(feature = "no_std"))]
9use std::io::{Cursor, Read};
10
11pub trait Decodable<'a>: Sized {
16 fn get_structure(data: &[u8]) -> Result<Vec<FieldMarker>, Error>;
21
22 fn from_decoded_fields(data: Vec<DecodableField<'a>>) -> Result<Self, Error>;
27
28 fn from_bytes(data: &'a mut [u8]) -> Result<Self, Error> {
34 let structure = Self::get_structure(data)?;
35 let mut fields = Vec::new();
36 let mut tail = data;
37
38 for field in structure {
39 let field_size = field.size_hint_(tail, 0)?;
40 if field_size > tail.len() {
41 return Err(Error::DecodableConversionError);
42 }
43 let (head, t) = tail.split_at_mut(field_size);
44 tail = t;
45 fields.push(field.decode(head)?);
46 }
47 Self::from_decoded_fields(fields)
48 }
49
50 #[cfg(not(feature = "no_std"))]
55 fn from_reader(reader: &mut impl Read) -> Result<Self, Error> {
56 let mut data = Vec::new();
57 reader.read_to_end(&mut data)?;
58
59 let structure = Self::get_structure(&data[..])?;
60
61 let mut fields = Vec::new();
62 let mut reader = Cursor::new(data);
63
64 for field in structure {
65 fields.push(field.from_reader(&mut reader)?);
66 }
67 Self::from_decoded_fields(fields)
68 }
69}
70
71#[derive(Debug, Clone, Copy)]
76pub enum PrimitiveMarker {
77 U8,
78 U16,
79 Bool,
80 U24,
81 U256,
82 Signature,
83 U32,
84 U32AsRef,
85 F32,
86 U64,
87 B032,
88 B0255,
89 B064K,
90 B016M,
91}
92
93#[derive(Debug, Clone)]
98pub enum FieldMarker {
99 Primitive(PrimitiveMarker),
101
102 Struct(Vec<FieldMarker>),
104}
105
106pub trait GetMarker {
111 fn get_marker() -> FieldMarker;
114}
115
116#[derive(Debug)]
119pub enum DecodablePrimitive<'a> {
120 U8(u8),
121 U16(u16),
122 Bool(bool),
123 U24(U24),
124 U256(U256<'a>),
125 Signature(Signature<'a>),
126 U32(u32),
127 U32AsRef(U32AsRef<'a>),
128 F32(f32),
129 U64(u64),
130 B032(B032<'a>),
131 B0255(B0255<'a>),
132 B064K(B064K<'a>),
133 B016M(B016M<'a>),
134}
135
136#[derive(Debug)]
144pub enum DecodableField<'a> {
145 Primitive(DecodablePrimitive<'a>),
147
148 Struct(Vec<DecodableField<'a>>),
150}
151
152impl SizeHint for PrimitiveMarker {
153 fn size_hint(_data: &[u8], _offset: usize) -> Result<usize, Error> {
155 unimplemented!()
156 }
157
158 fn size_hint_(&self, data: &[u8], offset: usize) -> Result<usize, Error> {
159 match self {
160 Self::U8 => u8::size_hint(data, offset),
161 Self::U16 => u16::size_hint(data, offset),
162 Self::Bool => bool::size_hint(data, offset),
163 Self::U24 => U24::size_hint(data, offset),
164 Self::U256 => U256::size_hint(data, offset),
165 Self::Signature => Signature::size_hint(data, offset),
166 Self::U32 => u32::size_hint(data, offset),
167 Self::U32AsRef => U32AsRef::size_hint(data, offset),
168 Self::F32 => f32::size_hint(data, offset),
169 Self::U64 => u64::size_hint(data, offset),
170 Self::B032 => B032::size_hint(data, offset),
171 Self::B0255 => B0255::size_hint(data, offset),
172 Self::B064K => B064K::size_hint(data, offset),
173 Self::B016M => B016M::size_hint(data, offset),
174 }
175 }
176}
177
178impl SizeHint for FieldMarker {
179 fn size_hint(_data: &[u8], _offset: usize) -> Result<usize, Error> {
181 unimplemented!()
182 }
183
184 fn size_hint_(&self, data: &[u8], offset: usize) -> Result<usize, Error> {
185 match self {
186 Self::Primitive(p) => p.size_hint_(data, offset),
187 Self::Struct(ps) => {
188 let mut size = 0;
189 for p in ps {
190 size += p.size_hint_(data, offset + size)?;
191 }
192 Ok(size)
193 }
194 }
195 }
196}
197
198impl SizeHint for Vec<FieldMarker> {
199 fn size_hint(_data: &[u8], _offset: usize) -> Result<usize, Error> {
201 unimplemented!()
202 }
203
204 fn size_hint_(&self, data: &[u8], offset: usize) -> Result<usize, Error> {
205 let mut size = 0;
206 for field in self {
207 let field_size = field.size_hint_(data, offset + size)?;
208 size += field_size;
209 }
210 Ok(size)
211 }
212}
213
214impl From<PrimitiveMarker> for FieldMarker {
215 fn from(v: PrimitiveMarker) -> Self {
216 FieldMarker::Primitive(v)
217 }
218}
219
220impl TryFrom<Vec<FieldMarker>> for FieldMarker {
221 type Error = crate::Error;
222
223 fn try_from(mut v: Vec<FieldMarker>) -> Result<Self, crate::Error> {
224 match v.len() {
225 0 => Err(crate::Error::VoidFieldMarker),
229 1 => Ok(v.pop().unwrap()),
231 _ => Ok(FieldMarker::Struct(v)),
232 }
233 }
234}
235
236impl<'a> From<DecodableField<'a>> for Vec<DecodableField<'a>> {
237 fn from(v: DecodableField<'a>) -> Self {
238 match v {
239 DecodableField::Primitive(p) => vec![DecodableField::Primitive(p)],
240 DecodableField::Struct(ps) => ps,
241 }
242 }
243}
244
245impl PrimitiveMarker {
246 fn decode<'a>(&self, data: &'a mut [u8], offset: usize) -> DecodablePrimitive<'a> {
250 match self {
251 Self::U8 => DecodablePrimitive::U8(u8::from_bytes_unchecked(&mut data[offset..])),
252 Self::U16 => DecodablePrimitive::U16(u16::from_bytes_unchecked(&mut data[offset..])),
253 Self::Bool => DecodablePrimitive::Bool(bool::from_bytes_unchecked(&mut data[offset..])),
254 Self::U24 => DecodablePrimitive::U24(U24::from_bytes_unchecked(&mut data[offset..])),
255 Self::U256 => DecodablePrimitive::U256(U256::from_bytes_unchecked(&mut data[offset..])),
256 Self::Signature => {
257 DecodablePrimitive::Signature(Signature::from_bytes_unchecked(&mut data[offset..]))
258 }
259 Self::U32 => DecodablePrimitive::U32(u32::from_bytes_unchecked(&mut data[offset..])),
260 Self::U32AsRef => {
261 DecodablePrimitive::U32AsRef(U32AsRef::from_bytes_unchecked(&mut data[offset..]))
262 }
263 Self::F32 => DecodablePrimitive::F32(f32::from_bytes_unchecked(&mut data[offset..])),
264 Self::U64 => DecodablePrimitive::U64(u64::from_bytes_unchecked(&mut data[offset..])),
265 Self::B032 => DecodablePrimitive::B032(B032::from_bytes_unchecked(&mut data[offset..])),
266 Self::B0255 => {
267 DecodablePrimitive::B0255(B0255::from_bytes_unchecked(&mut data[offset..]))
268 }
269 Self::B064K => {
270 DecodablePrimitive::B064K(B064K::from_bytes_unchecked(&mut data[offset..]))
271 }
272 Self::B016M => {
273 DecodablePrimitive::B016M(B016M::from_bytes_unchecked(&mut data[offset..]))
274 }
275 }
276 }
277
278 #[allow(clippy::wrong_self_convention)]
282 #[cfg(not(feature = "no_std"))]
283 fn from_reader<'a>(&self, reader: &mut impl Read) -> Result<DecodablePrimitive<'a>, Error> {
284 match self {
285 Self::U8 => Ok(DecodablePrimitive::U8(u8::from_reader_(reader)?)),
286 Self::U16 => Ok(DecodablePrimitive::U16(u16::from_reader_(reader)?)),
287 Self::Bool => Ok(DecodablePrimitive::Bool(bool::from_reader_(reader)?)),
288 Self::U24 => Ok(DecodablePrimitive::U24(U24::from_reader_(reader)?)),
289 Self::U256 => Ok(DecodablePrimitive::U256(U256::from_reader_(reader)?)),
290 Self::Signature => Ok(DecodablePrimitive::Signature(Signature::from_reader_(
291 reader,
292 )?)),
293 Self::U32 => Ok(DecodablePrimitive::U32(u32::from_reader_(reader)?)),
294 Self::U32AsRef => Ok(DecodablePrimitive::U32AsRef(U32AsRef::from_reader_(
295 reader,
296 )?)),
297 Self::F32 => Ok(DecodablePrimitive::F32(f32::from_reader_(reader)?)),
298 Self::U64 => Ok(DecodablePrimitive::U64(u64::from_reader_(reader)?)),
299 Self::B032 => Ok(DecodablePrimitive::B032(B032::from_reader_(reader)?)),
300 Self::B0255 => Ok(DecodablePrimitive::B0255(B0255::from_reader_(reader)?)),
301 Self::B064K => Ok(DecodablePrimitive::B064K(B064K::from_reader_(reader)?)),
302 Self::B016M => Ok(DecodablePrimitive::B016M(B016M::from_reader_(reader)?)),
303 }
304 }
305}
306
307impl GetSize for DecodablePrimitive<'_> {
308 fn get_size(&self) -> usize {
309 match self {
310 DecodablePrimitive::U8(v) => v.get_size(),
311 DecodablePrimitive::U16(v) => v.get_size(),
312 DecodablePrimitive::Bool(v) => v.get_size(),
313 DecodablePrimitive::U24(v) => v.get_size(),
314 DecodablePrimitive::U256(v) => v.get_size(),
315 DecodablePrimitive::Signature(v) => v.get_size(),
316 DecodablePrimitive::U32(v) => v.get_size(),
317 DecodablePrimitive::U32AsRef(v) => v.get_size(),
318 DecodablePrimitive::F32(v) => v.get_size(),
319 DecodablePrimitive::U64(v) => v.get_size(),
320 DecodablePrimitive::B032(v) => v.get_size(),
321 DecodablePrimitive::B0255(v) => v.get_size(),
322 DecodablePrimitive::B064K(v) => v.get_size(),
323 DecodablePrimitive::B016M(v) => v.get_size(),
324 }
325 }
326}
327
328impl FieldMarker {
329 pub(crate) fn decode<'a>(&self, data: &'a mut [u8]) -> Result<DecodableField<'a>, Error> {
334 match self {
335 Self::Primitive(p) => Ok(DecodableField::Primitive(p.decode(data, 0))),
336 Self::Struct(ps) => {
337 let mut decodeds = Vec::new();
338 let mut tail = data;
339 for p in ps {
340 let field_size = p.size_hint_(tail, 0)?;
341 let (head, t) = tail.split_at_mut(field_size);
342 tail = t;
343 decodeds.push(p.decode(head)?);
344 }
345 Ok(DecodableField::Struct(decodeds))
346 }
347 }
348 }
349
350 #[allow(clippy::wrong_self_convention)]
351 #[cfg(not(feature = "no_std"))]
352 #[allow(clippy::wrong_self_convention)]
353 pub(crate) fn from_reader<'a>(
354 &self,
355 reader: &mut impl Read,
356 ) -> Result<DecodableField<'a>, Error> {
357 match self {
358 Self::Primitive(p) => Ok(DecodableField::Primitive(p.from_reader(reader)?)),
359 Self::Struct(ps) => {
360 let mut decodeds = Vec::new();
361 for p in ps {
362 decodeds.push(p.from_reader(reader)?);
363 }
364 Ok(DecodableField::Struct(decodeds))
365 }
366 }
367 }
368}