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}