der/asn1/
sequence_of.rs

1//! ASN.1 `SEQUENCE OF` support.
2
3use crate::{
4    arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag,
5    Header, Length, Reader, Result, Tag, ValueOrd, Writer,
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.push(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: Decode<'a>,
68{
69    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
70        reader.read_nested(header.length, |reader| {
71            let mut sequence_of = Self::new();
72
73            while !reader.is_finished() {
74                sequence_of.add(T::decode(reader)?)?;
75            }
76
77            Ok(sequence_of)
78        })
79    }
80}
81
82impl<T, const N: usize> EncodeValue for SequenceOf<T, N>
83where
84    T: Encode,
85{
86    fn value_len(&self) -> Result<Length> {
87        self.iter()
88            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
89    }
90
91    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
92        for elem in self.iter() {
93            elem.encode(writer)?;
94        }
95
96        Ok(())
97    }
98}
99
100impl<T, const N: usize> FixedTag for SequenceOf<T, N> {
101    const TAG: Tag = Tag::Sequence;
102}
103
104impl<T, const N: usize> ValueOrd for SequenceOf<T, N>
105where
106    T: DerOrd,
107{
108    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
109        iter_cmp(self.iter(), other.iter())
110    }
111}
112
113/// Iterator over the elements of an [`SequenceOf`].
114#[derive(Clone, Debug)]
115pub struct SequenceOfIter<'a, T> {
116    /// Inner iterator.
117    inner: arrayvec::Iter<'a, T>,
118}
119
120impl<'a, T> Iterator for SequenceOfIter<'a, T> {
121    type Item = &'a T;
122
123    fn next(&mut self) -> Option<&'a T> {
124        self.inner.next()
125    }
126}
127
128impl<'a, T> ExactSizeIterator for SequenceOfIter<'a, T> {}
129
130impl<'a, T, const N: usize> DecodeValue<'a> for [T; N]
131where
132    T: Decode<'a>,
133{
134    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
135        let sequence_of = SequenceOf::<T, N>::decode_value(reader, header)?;
136
137        // TODO(tarcieri): use `[T; N]::try_map` instead of `expect` when stable
138        if sequence_of.inner.len() == N {
139            Ok(sequence_of
140                .inner
141                .into_array()
142                .map(|elem| elem.expect("arrayvec length mismatch")))
143        } else {
144            Err(Self::TAG.length_error())
145        }
146    }
147}
148
149impl<T, const N: usize> EncodeValue for [T; N]
150where
151    T: Encode,
152{
153    fn value_len(&self) -> Result<Length> {
154        self.iter()
155            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
156    }
157
158    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
159        for elem in self {
160            elem.encode(writer)?;
161        }
162
163        Ok(())
164    }
165}
166
167impl<T, const N: usize> FixedTag for [T; N] {
168    const TAG: Tag = Tag::Sequence;
169}
170
171impl<T, const N: usize> ValueOrd for [T; N]
172where
173    T: DerOrd,
174{
175    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
176        iter_cmp(self.iter(), other.iter())
177    }
178}
179
180#[cfg(feature = "alloc")]
181impl<'a, T> DecodeValue<'a> for Vec<T>
182where
183    T: Decode<'a>,
184{
185    fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self> {
186        reader.read_nested(header.length, |reader| {
187            let mut sequence_of = Self::new();
188
189            while !reader.is_finished() {
190                sequence_of.push(T::decode(reader)?);
191            }
192
193            Ok(sequence_of)
194        })
195    }
196}
197
198#[cfg(feature = "alloc")]
199impl<T> EncodeValue for Vec<T>
200where
201    T: Encode,
202{
203    fn value_len(&self) -> Result<Length> {
204        self.iter()
205            .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
206    }
207
208    fn encode_value(&self, writer: &mut impl Writer) -> Result<()> {
209        for elem in self {
210            elem.encode(writer)?;
211        }
212
213        Ok(())
214    }
215}
216
217#[cfg(feature = "alloc")]
218impl<T> FixedTag for Vec<T> {
219    const TAG: Tag = Tag::Sequence;
220}
221
222#[cfg(feature = "alloc")]
223impl<T> ValueOrd for Vec<T>
224where
225    T: DerOrd,
226{
227    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
228        iter_cmp(self.iter(), other.iter())
229    }
230}