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`].
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

            
59
impl<T, const N: usize> Default for SequenceOf<T, N> {
60
    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
{
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
{
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

            
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
{
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

            
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
{
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
{
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

            
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
{
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
{
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
{
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")]
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
{
227
    fn value_cmp(&self, other: &Self) -> Result<Ordering> {
228
        iter_cmp(self.iter(), other.iter())
229
    }
230
}