der/asn1/
sequence_of.rs

1//! ASN.1 `SEQUENCE OF` support.
2
3use crate::{
4    arrayvec, ArrayVec, Decodable, DecodeValue, Decoder, DerOrd, Encodable, EncodeValue, Encoder,
5    ErrorKind, FixedTag, Length, Result, Tag, ValueOrd,
6};
7use core::cmp::Ordering;
8
9#[cfg(feature = "alloc")]
10use alloc::vec::Vec;
11
12/// ASN.1 `SEQUENCE OF` backed by an array.
13///
14/// This type implements an append-only `SEQUENCE OF` type which is stack-based
15/// and does not depend on `alloc` support.
16// TODO(tarcieri): use `ArrayVec` when/if it's merged into `core`
17// See: https://github.com/rust-lang/rfcs/pull/2990
18#[derive(Clone, Debug, Eq, PartialEq)]
19pub struct SequenceOf<T, const N: usize> {
20    inner: ArrayVec<T, N>,
21}
22
23impl<T, const N: usize> SequenceOf<T, N> {
24    /// Create a new [`SequenceOf`].
25    pub fn new() -> Self {
26        Self {
27            inner: ArrayVec::new(),
28        }
29    }
30
31    /// Add an element to this [`SequenceOf`].
32    pub fn add(&mut self, element: T) -> Result<()> {
33        self.inner.add(element)
34    }
35
36    /// Get an element of this [`SequenceOf`].
37    pub fn get(&self, index: usize) -> Option<&T> {
38        self.inner.get(index)
39    }
40
41    /// Iterate over the elements in this [`SequenceOf`].
42    pub fn iter(&self) -> SequenceOfIter<'_, T> {
43        SequenceOfIter {
44            inner: self.inner.iter(),
45        }
46    }
47
48    /// Is this [`SequenceOf`] empty?
49    pub fn is_empty(&self) -> bool {
50        self.inner.is_empty()
51    }
52
53    /// Number of elements in this [`SequenceOf`].
54    pub fn len(&self) -> usize {
55        self.inner.len()
56    }
57}
58
59impl<T, const N: usize> Default for SequenceOf<T, N> {
60    fn default() -> Self {
61        Self::new()
62    }
63}
64
65impl<'a, T, const N: usize> DecodeValue<'a> for SequenceOf<T, N>
66where
67    T: Decodable<'a>,
68{
69    fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
70        let end_pos = (decoder.position() + length)?;
71        let mut sequence_of = Self::new();
72
73        while decoder.position() < end_pos {
74            sequence_of.add(decoder.decode()?)?;
75        }
76
77        if decoder.position() != end_pos {
78            decoder.error(ErrorKind::Length { tag: Self::TAG });
79        }
80
81        Ok(sequence_of)
82    }
83}
84
85impl<T, const N: usize> EncodeValue for SequenceOf<T, N>
86where
87    T: Encodable,
88{
89    fn value_len(&self) -> Result<Length> {
90        self.iter()
91            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
92    }
93
94    fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
95        for elem in self.iter() {
96            elem.encode(encoder)?;
97        }
98
99        Ok(())
100    }
101}
102
103impl<T, const N: usize> FixedTag for SequenceOf<T, N> {
104    const TAG: Tag = Tag::Sequence;
105}
106
107impl<T, const N: usize> ValueOrd for SequenceOf<T, N>
108where
109    T: DerOrd,
110{
111    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
112        value_cmp(self.iter(), other.iter())
113    }
114}
115
116/// Iterator over the elements of an [`SequenceOf`].
117#[derive(Clone, Debug)]
118pub struct SequenceOfIter<'a, T> {
119    /// Inner iterator.
120    inner: arrayvec::Iter<'a, T>,
121}
122
123impl<'a, T> Iterator for SequenceOfIter<'a, T> {
124    type Item = &'a T;
125
126    fn next(&mut self) -> Option<&'a T> {
127        self.inner.next()
128    }
129}
130
131impl<'a, T, const N: usize> DecodeValue<'a> for [T; N]
132where
133    T: Decodable<'a>,
134{
135    fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
136        SequenceOf::decode_value(decoder, length)?
137            .inner
138            .try_into_array()
139    }
140}
141
142impl<T, const N: usize> EncodeValue for [T; N]
143where
144    T: Encodable,
145{
146    fn value_len(&self) -> Result<Length> {
147        self.iter()
148            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
149    }
150
151    fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
152        for elem in self {
153            elem.encode(encoder)?;
154        }
155
156        Ok(())
157    }
158}
159
160impl<T, const N: usize> FixedTag for [T; N] {
161    const TAG: Tag = Tag::Sequence;
162}
163
164impl<T, const N: usize> ValueOrd for [T; N]
165where
166    T: DerOrd,
167{
168    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
169        value_cmp(self.iter(), other.iter())
170    }
171}
172
173#[cfg(feature = "alloc")]
174#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
175impl<'a, T> DecodeValue<'a> for Vec<T>
176where
177    T: Decodable<'a>,
178{
179    fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
180        let end_pos = (decoder.position() + length)?;
181        let mut sequence_of = Self::new();
182
183        while decoder.position() < end_pos {
184            sequence_of.push(decoder.decode()?);
185        }
186
187        if decoder.position() != end_pos {
188            decoder.error(ErrorKind::Length { tag: Self::TAG });
189        }
190
191        Ok(sequence_of)
192    }
193}
194
195#[cfg(feature = "alloc")]
196#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
197impl<T> EncodeValue for Vec<T>
198where
199    T: Encodable,
200{
201    fn value_len(&self) -> Result<Length> {
202        self.iter()
203            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
204    }
205
206    fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
207        for elem in self {
208            elem.encode(encoder)?;
209        }
210
211        Ok(())
212    }
213}
214
215#[cfg(feature = "alloc")]
216#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
217impl<T> FixedTag for Vec<T> {
218    const TAG: Tag = Tag::Sequence;
219}
220
221#[cfg(feature = "alloc")]
222#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
223impl<T> ValueOrd for Vec<T>
224where
225    T: DerOrd,
226{
227    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
228        value_cmp(self.iter(), other.iter())
229    }
230}
231
232/// Compare two `SEQUENCE OF`s by value.
233fn value_cmp<'a, I, T: 'a>(a: I, b: I) -> Result<Ordering>
234where
235    I: Iterator<Item = &'a T>,
236    T: DerOrd,
237{
238    for (value1, value2) in a.zip(b) {
239        match value1.der_cmp(value2)? {
240            Ordering::Equal => (),
241            other => return Ok(other),
242        }
243    }
244
245    Ok(Ordering::Equal)
246}