1use crate::{BinaryReader, BinaryReaderError, Result};
17use ::core::fmt;
18use ::core::marker;
19use ::core::ops::Range;
20
21#[cfg(feature = "component-model")]
22mod component;
23mod core;
24
25#[cfg(feature = "component-model")]
26pub use self::component::*;
27pub use self::core::*;
28
29pub trait FromReader<'a>: Sized {
35 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self>;
38}
39
40impl<'a> FromReader<'a> for bool {
41 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
42 match reader.read_u8()? {
43 0 => Ok(false),
44 1 => Ok(true),
45 _ => Err(BinaryReaderError::new(
46 "invalid boolean value",
47 reader.original_position() - 1,
48 )),
49 }
50 }
51}
52
53impl<'a> FromReader<'a> for u32 {
54 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
55 reader.read_var_u32()
56 }
57}
58
59impl<'a> FromReader<'a> for &'a str {
60 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
61 reader.read_string()
62 }
63}
64
65impl<'a, T, U> FromReader<'a> for (T, U)
66where
67 T: FromReader<'a>,
68 U: FromReader<'a>,
69{
70 fn from_reader(reader: &mut BinaryReader<'a>) -> Result<Self> {
71 Ok((reader.read()?, reader.read()?))
72 }
73}
74
75pub struct SectionLimited<'a, T> {
85 reader: BinaryReader<'a>,
86 count: u32,
87 _marker: marker::PhantomData<T>,
88}
89
90impl<'a, T> SectionLimited<'a, T> {
91 pub fn new(mut reader: BinaryReader<'a>) -> Result<Self> {
102 let count = reader.read_var_u32()?;
103 Ok(SectionLimited {
104 reader,
105 count,
106 _marker: marker::PhantomData,
107 })
108 }
109
110 pub fn count(&self) -> u32 {
112 self.count
113 }
114
115 pub fn original_position(&self) -> usize {
117 self.reader.original_position()
118 }
119
120 pub fn range(&self) -> Range<usize> {
123 self.reader.range()
124 }
125
126 pub fn into_iter_with_offsets(self) -> SectionLimitedIntoIterWithOffsets<'a, T>
129 where
130 T: FromReader<'a>,
131 {
132 SectionLimitedIntoIterWithOffsets {
133 iter: self.into_iter(),
134 }
135 }
136}
137
138impl<T> Clone for SectionLimited<'_, T> {
139 fn clone(&self) -> Self {
140 SectionLimited {
141 reader: self.reader.clone(),
142 count: self.count,
143 _marker: self._marker,
144 }
145 }
146}
147
148impl<T> fmt::Debug for SectionLimited<'_, T> {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 f.debug_struct("SectionLimited")
151 .field("count", &self.count)
152 .field("range", &self.range())
153 .finish()
154 }
155}
156
157impl<'a, T> IntoIterator for SectionLimited<'a, T>
158where
159 T: FromReader<'a>,
160{
161 type Item = Result<T>;
162 type IntoIter = SectionLimitedIntoIter<'a, T>;
163
164 fn into_iter(self) -> Self::IntoIter {
165 SectionLimitedIntoIter {
166 remaining: self.count,
167 section: self,
168 end: false,
169 }
170 }
171}
172
173pub struct SectionLimitedIntoIter<'a, T> {
178 section: SectionLimited<'a, T>,
179 remaining: u32,
180 end: bool,
181}
182
183impl<T> SectionLimitedIntoIter<'_, T> {
184 pub fn original_position(&self) -> usize {
186 self.section.reader.original_position()
187 }
188}
189
190impl<'a, T> Iterator for SectionLimitedIntoIter<'a, T>
191where
192 T: FromReader<'a>,
193{
194 type Item = Result<T>;
195
196 fn next(&mut self) -> Option<Result<T>> {
197 if self.end {
198 return None;
199 }
200 if self.remaining == 0 {
201 self.end = true;
202 if self.section.reader.eof() {
203 return None;
204 }
205 return Some(Err(BinaryReaderError::new(
206 "section size mismatch: unexpected data at the end of the section",
207 self.section.reader.original_position(),
208 )));
209 }
210 let result = self.section.reader.read();
211 self.end = result.is_err();
212 self.remaining -= 1;
213 Some(result)
214 }
215
216 fn size_hint(&self) -> (usize, Option<usize>) {
217 let remaining = self.remaining as usize;
218 (remaining, Some(remaining))
219 }
220}
221
222impl<'a, T> ExactSizeIterator for SectionLimitedIntoIter<'a, T> where T: FromReader<'a> {}
223
224pub struct SectionLimitedIntoIterWithOffsets<'a, T> {
226 iter: SectionLimitedIntoIter<'a, T>,
227}
228
229impl<'a, T> Iterator for SectionLimitedIntoIterWithOffsets<'a, T>
230where
231 T: FromReader<'a>,
232{
233 type Item = Result<(usize, T)>;
234
235 fn next(&mut self) -> Option<Self::Item> {
236 let pos = self.iter.section.reader.original_position();
237 Some(self.iter.next()?.map(|item| (pos, item)))
238 }
239
240 fn size_hint(&self) -> (usize, Option<usize>) {
241 self.iter.size_hint()
242 }
243}
244
245impl<'a, T> ExactSizeIterator for SectionLimitedIntoIterWithOffsets<'a, T> where T: FromReader<'a> {}
246
247pub trait Subsection<'a>: Sized {
254 fn from_reader(id: u8, reader: BinaryReader<'a>) -> Result<Self>;
257}
258
259pub struct Subsections<'a, T> {
265 reader: BinaryReader<'a>,
266 _marker: marker::PhantomData<T>,
267}
268
269impl<'a, T> Subsections<'a, T> {
270 pub fn new(reader: BinaryReader<'a>) -> Self {
273 Subsections {
274 reader,
275 _marker: marker::PhantomData,
276 }
277 }
278
279 pub fn original_position(&self) -> usize {
281 self.reader.original_position()
282 }
283
284 pub fn range(&self) -> Range<usize> {
287 self.reader.range()
288 }
289
290 fn read(&mut self) -> Result<T>
291 where
292 T: Subsection<'a>,
293 {
294 let subsection_id = self.reader.read_u7()?;
295 let reader = self.reader.read_reader()?;
296 T::from_reader(subsection_id, reader)
297 }
298}
299
300impl<T> Clone for Subsections<'_, T> {
301 fn clone(&self) -> Self {
302 Subsections {
303 reader: self.reader.clone(),
304 _marker: self._marker,
305 }
306 }
307}
308
309impl<T> fmt::Debug for Subsections<'_, T> {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 f.debug_struct("Subsections")
312 .field("range", &self.range())
313 .finish()
314 }
315}
316
317impl<'a, T> Iterator for Subsections<'a, T>
318where
319 T: Subsection<'a>,
320{
321 type Item = Result<T>;
322
323 fn next(&mut self) -> Option<Result<T>> {
324 if self.reader.eof() {
325 None
326 } else {
327 Some(self.read())
328 }
329 }
330}