1use crate::vector::Vector;
2use crate::{reader::Reader, VectorFactory};
3use core::fmt::{Display, Formatter};
4use core::str::Utf8Error;
5
6pub trait Decode<V: VectorFactory>: Sized {
7 fn decode(reader: &mut Reader) -> Result<Self, DecodeError>;
8
9 fn decode_vector(reader: &mut Reader) -> Result<V::Vector<Self>, DecodeError> {
10 let len = reader.read_usize()?;
11 let mut items = V::create_vector(Some(len));
12 for _ in 0..len {
13 items.push(Self::decode(reader)?);
14 }
15 Ok(items)
16 }
17}
18
19impl<V: VectorFactory> Decode<V> for u8 {
20 fn decode(reader: &mut Reader) -> Result<Self, DecodeError> {
21 reader.read_u8()
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub enum DecodeError {
27 UnexpectedEndOfBytes,
28 InvalidMagic {
29 value: [u8; 4],
30 },
31 InvalidVersion {
32 value: [u8; 4],
33 },
34 InvalidSectionId {
35 value: u8,
36 },
37 InvalidImportDescTag {
38 value: u8,
39 },
40 InvalidExportDescTag {
41 value: u8,
42 },
43 InvalidLimitsFlag {
44 value: u8,
45 },
46 InvalidValType {
47 value: u8,
48 },
49 InvalidMutabilityFlag {
50 value: u8,
51 },
52 InvalidElemType {
53 value: u8,
54 },
55 InvalidFuncTypeTag {
56 value: u8,
57 },
58 InvalidMemoryCount {
59 value: usize,
60 },
61 InvalidTableCount {
62 value: usize,
63 },
64 InvalidResultArity {
65 value: usize,
66 },
67 InvalidMemIdx {
68 value: u32,
69 },
70 InvalidTableIdx {
71 value: u32,
72 },
73 InvalidOpcode {
74 value: u8,
75 },
76 UnexpectedExpr,
77 InvalidSectionOrder {
78 last_section_id: u8,
79 current_section_id: u8,
80 },
81 InvalidSectionByteSize {
82 section_id: u8,
83 expected_byte_size: usize,
84 actual_byte_size: usize,
85 },
86 InvalidUtf8(Utf8Error),
87 MismatchFunctionAndCodeSectionSize {
88 function_section_size: usize,
89 code_section_size: usize,
90 },
91 MalformedInteger,
92}
93
94impl Display for DecodeError {
95 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
96 match self {
97 Self::UnexpectedEndOfBytes => write!(f, "Unexpected end-of-bytes"),
98 Self::InvalidMagic { value } => write!(f, "Invalid magic number {value:?}"),
99 Self::InvalidVersion { value } => write!(f, "Invalid version number {value:?}"),
100 Self::InvalidSectionId { value } => write!(f, "Invalid section ID {value:?}"),
101 Self::InvalidImportDescTag { value } => {
102 write!(f, "Invalid import description tag {value:?})")
103 }
104 Self::InvalidExportDescTag { value } => {
105 write!(f, "Invalid export description tag {value:?})")
106 }
107 Self::InvalidLimitsFlag { value } => write!(f, "Invalid limits flag {value:?}"),
108 Self::InvalidValType { value } => write!(f, "Invalid value type {value:?}"),
109 Self::InvalidMutabilityFlag { value } => write!(f, "Invalid mutability flag {value:?}"),
110 Self::InvalidElemType { value } => write!(f, "Invalid element type {value:?}"),
111 Self::InvalidFuncTypeTag { value } => write!(f, "Invalid function type {value:?}"),
112 Self::InvalidMemoryCount { value } => write!(f, "Invalid memory count {value:?}"),
113 Self::InvalidTableCount { value } => write!(f, "Invalid table count {value:?}"),
114 Self::InvalidResultArity { value } => write!(f, "Invalid result arity {value:?}"),
115 Self::InvalidMemIdx { value } => write!(f, "Invalid memory index {value:?}"),
116 Self::InvalidTableIdx { value } => write!(f, "Invalid table index {value:?}"),
117 Self::InvalidOpcode { value } => write!(f, "Invalid opcode {value:?}"),
118 Self::UnexpectedExpr => write!(f, "Unexpected expression"),
119 Self::InvalidSectionOrder {
120 last_section_id,
121 current_section_id,
122 } => write!(
123 f,
124 "Invalid section order (last={last_section_id:?}), current={current_section_id:?})"
125 ),
126 Self::InvalidSectionByteSize {
127 section_id,
128 expected_byte_size,
129 actual_byte_size
130 } => write!(f, "Invalid section {section_id:?} byte size (expected={expected_byte_size:?} bytes, actual={actual_byte_size:?} bytes)"),
131 Self::InvalidUtf8(e) => write!(f,"Invalid UTF-8 bytes ({e})"),
132 Self::MismatchFunctionAndCodeSectionSize {
133 function_section_size,
134 code_section_size
135 } => write!(f, "Mismatch function section size ({function_section_size:?}) and code section size ({code_section_size:?})"),
136 Self::MalformedInteger => write!(f,"Malformed LEB128 integer"),
137 }
138 }
139}
140
141#[cfg(feature = "std")]
142impl std::error::Error for DecodeError {}