1 //! ASN.1 `SEQUENCE OF` support.
2 
3 use crate::{
4     arrayvec, ord::iter_cmp, ArrayVec, Decode, DecodeValue, DerOrd, Encode, EncodeValue, FixedTag,
5     Header, Length, Reader, Result, Tag, ValueOrd, Writer,
6 };
7 use core::cmp::Ordering;
8 
9 #[cfg(feature = "alloc")]
10 use 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)]
19 pub struct SequenceOf<T, const N: usize> {
20     inner: ArrayVec<T, N>,
21 }
22 
23 impl<T, const N: usize> SequenceOf<T, N> {
24     /// Create a new [`SequenceOf`].
new() -> Self25     pub fn new() -> Self {
26         Self {
27             inner: ArrayVec::new(),
28         }
29     }
30 
31     /// Add an element to this [`SequenceOf`].
add(&mut self, element: T) -> Result<()>32     pub fn add(&mut self, element: T) -> Result<()> {
33         self.inner.push(element)
34     }
35 
36     /// Get an element of this [`SequenceOf`].
get(&self, index: usize) -> Option<&T>37     pub fn get(&self, index: usize) -> Option<&T> {
38         self.inner.get(index)
39     }
40 
41     /// Iterate over the elements in this [`SequenceOf`].
iter(&self) -> SequenceOfIter<'_, T>42     pub fn iter(&self) -> SequenceOfIter<'_, T> {
43         SequenceOfIter {
44             inner: self.inner.iter(),
45         }
46     }
47 
48     /// Is this [`SequenceOf`] empty?
is_empty(&self) -> bool49     pub fn is_empty(&self) -> bool {
50         self.inner.is_empty()
51     }
52 
53     /// Number of elements in this [`SequenceOf`].
len(&self) -> usize54     pub fn len(&self) -> usize {
55         self.inner.len()
56     }
57 }
58 
59 impl<T, const N: usize> Default for SequenceOf<T, N> {
default() -> Self60     fn default() -> Self {
61         Self::new()
62     }
63 }
64 
65 impl<'a, T, const N: usize> DecodeValue<'a> for SequenceOf<T, N>
66 where
67     T: Decode<'a>,
68 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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 
82 impl<T, const N: usize> EncodeValue for SequenceOf<T, N>
83 where
84     T: Encode,
85 {
value_len(&self) -> Result<Length>86     fn value_len(&self) -> Result<Length> {
87         self.iter()
88             .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
89     }
90 
encode_value(&self, writer: &mut impl Writer) -> Result<()>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 
100 impl<T, const N: usize> FixedTag for SequenceOf<T, N> {
101     const TAG: Tag = Tag::Sequence;
102 }
103 
104 impl<T, const N: usize> ValueOrd for SequenceOf<T, N>
105 where
106     T: DerOrd,
107 {
value_cmp(&self, other: &Self) -> Result<Ordering>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)]
115 pub struct SequenceOfIter<'a, T> {
116     /// Inner iterator.
117     inner: arrayvec::Iter<'a, T>,
118 }
119 
120 impl<'a, T> Iterator for SequenceOfIter<'a, T> {
121     type Item = &'a T;
122 
next(&mut self) -> Option<&'a T>123     fn next(&mut self) -> Option<&'a T> {
124         self.inner.next()
125     }
126 }
127 
128 impl<'a, T> ExactSizeIterator for SequenceOfIter<'a, T> {}
129 
130 impl<'a, T, const N: usize> DecodeValue<'a> for [T; N]
131 where
132     T: Decode<'a>,
133 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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 
149 impl<T, const N: usize> EncodeValue for [T; N]
150 where
151     T: Encode,
152 {
value_len(&self) -> Result<Length>153     fn value_len(&self) -> Result<Length> {
154         self.iter()
155             .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
156     }
157 
encode_value(&self, writer: &mut impl Writer) -> Result<()>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 
167 impl<T, const N: usize> FixedTag for [T; N] {
168     const TAG: Tag = Tag::Sequence;
169 }
170 
171 impl<T, const N: usize> ValueOrd for [T; N]
172 where
173     T: DerOrd,
174 {
value_cmp(&self, other: &Self) -> Result<Ordering>175     fn value_cmp(&self, other: &Self) -> Result<Ordering> {
176         iter_cmp(self.iter(), other.iter())
177     }
178 }
179 
180 #[cfg(feature = "alloc")]
181 impl<'a, T> DecodeValue<'a> for Vec<T>
182 where
183     T: Decode<'a>,
184 {
decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> Result<Self>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")]
199 impl<T> EncodeValue for Vec<T>
200 where
201     T: Encode,
202 {
value_len(&self) -> Result<Length>203     fn value_len(&self) -> Result<Length> {
204         self.iter()
205             .fold(Ok(Length::ZERO), |len, elem| len + elem.encoded_len()?)
206     }
207 
encode_value(&self, writer: &mut impl Writer) -> Result<()>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")]
218 impl<T> FixedTag for Vec<T> {
219     const TAG: Tag = Tag::Sequence;
220 }
221 
222 #[cfg(feature = "alloc")]
223 impl<T> ValueOrd for Vec<T>
224 where
225     T: DerOrd,
226 {
value_cmp(&self, other: &Self) -> Result<Ordering>227     fn value_cmp(&self, other: &Self) -> Result<Ordering> {
228         iter_cmp(self.iter(), other.iter())
229     }
230 }
231