asn1_rs/asn1_types/sequence/
sequence_of.rs

1use crate::*;
2#[cfg(not(feature = "std"))]
3use alloc::vec::Vec;
4use core::convert::TryFrom;
5use core::fmt::{Debug, Display};
6use core::iter::FromIterator;
7use core::ops::{Deref, DerefMut};
8
9use self::debug::{trace, trace_generic};
10
11/// The `SEQUENCE OF` object is an ordered list of homogeneous types.
12///
13/// This type implements `Deref<Target = [T]>` and `DerefMut<Target = [T]>`, so all methods
14/// like `.iter()`, `.len()` and others can be used transparently as if using a vector.
15///
16/// # Examples
17///
18/// ```
19/// use asn1_rs::SequenceOf;
20/// use std::iter::FromIterator;
21///
22/// // build set
23/// let seq = SequenceOf::from_iter([2, 3, 4]);
24///
25/// // `seq` now contains the serialized DER representation of the array
26///
27/// // iterate objects
28/// let mut sum = 0;
29/// for item in seq.iter() {
30///     // item has type `Result<u32>`, since parsing the serialized bytes could fail
31///     sum += *item;
32/// }
33/// assert_eq!(sum, 9);
34///
35/// ```
36#[derive(Debug, PartialEq)]
37pub struct SequenceOf<T> {
38    pub(crate) items: Vec<T>,
39}
40
41impl<T> SequenceOf<T> {
42    /// Builds a `SEQUENCE OF` from the provided content
43    #[inline]
44    pub const fn new(items: Vec<T>) -> Self {
45        SequenceOf { items }
46    }
47
48    /// Converts `self` into a vector without clones or allocation.
49    #[inline]
50    pub fn into_vec(self) -> Vec<T> {
51        self.items
52    }
53
54    /// Appends an element to the back of a collection
55    #[inline]
56    pub fn push(&mut self, item: T) {
57        self.items.push(item)
58    }
59}
60
61impl<T> AsRef<[T]> for SequenceOf<T> {
62    fn as_ref(&self) -> &[T] {
63        &self.items
64    }
65}
66
67impl<T> AsMut<[T]> for SequenceOf<T> {
68    fn as_mut(&mut self) -> &mut [T] {
69        &mut self.items
70    }
71}
72
73impl<T> Deref for SequenceOf<T> {
74    type Target = [T];
75
76    fn deref(&self) -> &Self::Target {
77        &self.items
78    }
79}
80
81impl<T> DerefMut for SequenceOf<T> {
82    fn deref_mut(&mut self) -> &mut Self::Target {
83        &mut self.items
84    }
85}
86
87impl<T> From<SequenceOf<T>> for Vec<T> {
88    fn from(seq: SequenceOf<T>) -> Self {
89        seq.items
90    }
91}
92
93impl<T> FromIterator<T> for SequenceOf<T> {
94    fn from_iter<IT: IntoIterator<Item = T>>(iter: IT) -> Self {
95        let items = Vec::from_iter(iter);
96        SequenceOf::new(items)
97    }
98}
99
100impl<'a, T> TryFrom<Any<'a>> for SequenceOf<T>
101where
102    T: FromBer<'a>,
103{
104    type Error = Error;
105
106    fn try_from(any: Any<'a>) -> Result<Self> {
107        any.tag().assert_eq(Self::TAG)?;
108        if !any.header.is_constructed() {
109            return Err(Error::ConstructExpected);
110        }
111        let items = SequenceIterator::<T, BerParser>::new(any.data).collect::<Result<Vec<T>>>()?;
112        Ok(SequenceOf::new(items))
113    }
114}
115
116impl<T> CheckDerConstraints for SequenceOf<T>
117where
118    T: CheckDerConstraints,
119{
120    fn check_constraints(any: &Any) -> Result<()> {
121        any.tag().assert_eq(Self::TAG)?;
122        any.header.assert_constructed()?;
123        for item in SequenceIterator::<Any, DerParser>::new(any.data) {
124            let item = item?;
125            T::check_constraints(&item)?;
126        }
127        Ok(())
128    }
129}
130
131/// manual impl of FromDer, so we do not need to require `TryFrom<Any> + CheckDerConstraints`
132impl<'a, T, E> FromDer<'a, E> for SequenceOf<T>
133where
134    T: FromDer<'a, E>,
135    E: From<Error> + Display + Debug,
136{
137    fn from_der(bytes: &'a [u8]) -> ParseResult<Self, E> {
138        trace_generic(
139            core::any::type_name::<Self>(),
140            "SequenceOf::from_der",
141            |bytes| {
142                let (rem, any) = trace(core::any::type_name::<Self>(), parse_der_any, bytes)
143                    .map_err(Err::convert)?;
144                any.header
145                    .assert_tag(Self::TAG)
146                    .map_err(|e| Err::Error(e.into()))?;
147                let items = SequenceIterator::<T, DerParser, E>::new(any.data)
148                    .collect::<Result<Vec<T>, E>>()
149                    .map_err(Err::Error)?;
150                Ok((rem, SequenceOf::new(items)))
151            },
152            bytes,
153        )
154    }
155}
156
157impl<T> Tagged for SequenceOf<T> {
158    const TAG: Tag = Tag::Sequence;
159}
160
161#[cfg(feature = "std")]
162impl<T> ToDer for SequenceOf<T>
163where
164    T: ToDer,
165{
166    fn to_der_len(&self) -> Result<usize> {
167        self.items.to_der_len()
168    }
169
170    fn write_der_header(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> {
171        self.items.write_der_header(writer)
172    }
173
174    fn write_der_content(&self, writer: &mut dyn std::io::Write) -> SerializeResult<usize> {
175        self.items.write_der_content(writer)
176    }
177}
178
179#[cfg(test)]
180mod tests {
181    use crate::SequenceOf;
182    use core::iter::FromIterator;
183
184    /// Test use of object, available methods and syntax for different use cases
185    #[test]
186    fn use_sequence_of() {
187        let mut set = SequenceOf::from_iter([1, 2, 3]);
188        set.push(4);
189
190        // deref as slice
191        let sum: i32 = set.iter().sum();
192        assert_eq!(sum, 10);
193
194        // range operator
195        assert_eq!(&set[1..3], &[2, 3]);
196    }
197}