asn1_rs/asn1_types/sequence/
iterator.rs

1use crate::{ASN1Parser, BerParser, DerParser, Error, FromBer, FromDer};
2use core::marker::PhantomData;
3
4/// An Iterator over binary data, parsing elements of type `T`
5///
6/// This helps parsing `SEQUENCE OF` items of type `T`. The type of parser
7/// (BER/DER) is specified using the generic parameter `F` of this struct.
8///
9/// Note: the iterator must start on the sequence *contents*, not the sequence itself.
10///
11/// # Examples
12///
13/// ```rust
14/// use asn1_rs::{DerParser, Integer, SequenceIterator};
15///
16/// let data = &[0x30, 0x6, 0x2, 0x1, 0x1, 0x2, 0x1, 0x2];
17/// for (idx, item) in SequenceIterator::<Integer, DerParser>::new(&data[2..]).enumerate() {
18///     let item = item.unwrap(); // parsing could have failed
19///     let i = item.as_u32().unwrap(); // integer can be negative, or too large to fit into u32
20///     assert_eq!(i as usize, idx + 1);
21/// }
22/// ```
23#[derive(Debug)]
24pub struct SequenceIterator<'a, T, F, E = Error>
25where
26    F: ASN1Parser,
27{
28    data: &'a [u8],
29    has_error: bool,
30    _t: PhantomData<T>,
31    _f: PhantomData<F>,
32    _e: PhantomData<E>,
33}
34
35impl<'a, T, F, E> SequenceIterator<'a, T, F, E>
36where
37    F: ASN1Parser,
38{
39    pub fn new(data: &'a [u8]) -> Self {
40        SequenceIterator {
41            data,
42            has_error: false,
43            _t: PhantomData,
44            _f: PhantomData,
45            _e: PhantomData,
46        }
47    }
48}
49
50impl<'a, T, E> Iterator for SequenceIterator<'a, T, BerParser, E>
51where
52    T: FromBer<'a, E>,
53    E: From<Error>,
54{
55    type Item = Result<T, E>;
56
57    fn next(&mut self) -> Option<Self::Item> {
58        if self.has_error || self.data.is_empty() {
59            return None;
60        }
61        match T::from_ber(self.data) {
62            Ok((rem, obj)) => {
63                self.data = rem;
64                Some(Ok(obj))
65            }
66            Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => {
67                self.has_error = true;
68                Some(Err(e))
69            }
70
71            Err(nom::Err::Incomplete(n)) => {
72                self.has_error = true;
73                Some(Err(Error::Incomplete(n).into()))
74            }
75        }
76    }
77}
78
79impl<'a, T, E> Iterator for SequenceIterator<'a, T, DerParser, E>
80where
81    T: FromDer<'a, E>,
82    E: From<Error>,
83{
84    type Item = Result<T, E>;
85
86    fn next(&mut self) -> Option<Self::Item> {
87        if self.has_error || self.data.is_empty() {
88            return None;
89        }
90        match T::from_der(self.data) {
91            Ok((rem, obj)) => {
92                self.data = rem;
93                Some(Ok(obj))
94            }
95            Err(nom::Err::Error(e)) | Err(nom::Err::Failure(e)) => {
96                self.has_error = true;
97                Some(Err(e))
98            }
99
100            Err(nom::Err::Incomplete(n)) => {
101                self.has_error = true;
102                Some(Err(Error::Incomplete(n).into()))
103            }
104        }
105    }
106}