11//! ASN.1 `SEQUENCE OF` support.
22
33use crate :: {
4- Decode , DecodeValue , DerOrd , Encode , EncodeValue , Error , FixedTag , Header , Length , Reader , Tag ,
5- ValueOrd , Writer , ord:: iter_cmp,
4+ DerOrd , Encode , EncodeValue , Error , FixedTag , Length , Tag , ValueOrd , Writer , ord:: iter_cmp,
65} ;
76use core:: cmp:: Ordering ;
87
8+ #[ cfg( any( feature = "alloc" , feature = "heapless" ) ) ]
9+ use crate :: { Decode , DecodeValue , Header , Reader } ;
910#[ cfg( feature = "alloc" ) ]
1011use alloc:: vec:: Vec ;
12+ #[ cfg( feature = "heapless" ) ]
13+ use { crate :: ErrorKind , core:: slice} ;
14+
15+ /// ASN.1 `SEQUENCE OF` backed by an array.
16+ ///
17+ /// This type implements an append-only `SEQUENCE OF` type which is stack-based
18+ /// and does not depend on `alloc` support.
19+ // TODO(tarcieri): use `ArrayVec` when/if it's merged into `core` (rust-lang/rfcs#3316)
20+ #[ cfg( feature = "heapless" ) ]
21+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
22+ pub struct SequenceOf < T , const N : usize > {
23+ inner : heapless:: Vec < T , N > ,
24+ }
25+
26+ #[ cfg( feature = "heapless" ) ]
27+ impl < T , const N : usize > SequenceOf < T , N > {
28+ /// Create a new [`SequenceOf`].
29+ pub fn new ( ) -> Self {
30+ Self {
31+ inner : heapless:: Vec :: new ( ) ,
32+ }
33+ }
34+
35+ /// Add an element to this [`SequenceOf`].
36+ pub fn add ( & mut self , element : T ) -> Result < ( ) , Error > {
37+ self . inner
38+ . push ( element)
39+ . map_err ( |_| ErrorKind :: Overlength . into ( ) )
40+ }
41+
42+ /// Borrow the elements of this [`SequenceOf`] as a slice.
43+ pub fn as_slice ( & self ) -> & [ T ] {
44+ self . inner . as_slice ( )
45+ }
46+
47+ /// Borrow the elements of this [`SequenceOf`] mutably as a slice.
48+ pub fn as_mut_slice ( & mut self ) -> & mut [ T ] {
49+ self . inner . as_mut_slice ( )
50+ }
51+
52+ /// Get an element of this [`SequenceOf`].
53+ pub fn get ( & self , index : usize ) -> Option < & T > {
54+ self . inner . get ( index)
55+ }
56+
57+ /// Extract the inner `heapless::Vec`.
58+ pub fn into_inner ( self ) -> heapless:: Vec < T , N > {
59+ self . inner
60+ }
61+
62+ /// Iterate over the elements in this [`SequenceOf`].
63+ pub fn iter ( & self ) -> SequenceOfIter < ' _ , T > {
64+ SequenceOfIter {
65+ inner : self . inner . iter ( ) ,
66+ }
67+ }
68+
69+ /// Is this [`SequenceOf`] empty?
70+ pub fn is_empty ( & self ) -> bool {
71+ self . inner . is_empty ( )
72+ }
73+
74+ /// Number of elements in this [`SequenceOf`].
75+ pub fn len ( & self ) -> usize {
76+ self . inner . len ( )
77+ }
78+ }
79+
80+ #[ cfg( feature = "heapless" ) ]
81+ impl < T , const N : usize > AsRef < [ T ] > for SequenceOf < T , N > {
82+ fn as_ref ( & self ) -> & [ T ] {
83+ self . as_slice ( )
84+ }
85+ }
86+
87+ #[ cfg( feature = "heapless" ) ]
88+ impl < T , const N : usize > AsMut < [ T ] > for SequenceOf < T , N > {
89+ fn as_mut ( & mut self ) -> & mut [ T ] {
90+ self . as_mut_slice ( )
91+ }
92+ }
93+
94+ #[ cfg( feature = "heapless" ) ]
95+ impl < T , const N : usize > Default for SequenceOf < T , N > {
96+ fn default ( ) -> Self {
97+ Self :: new ( )
98+ }
99+ }
100+
101+ #[ cfg( feature = "heapless" ) ]
102+ impl < ' a , T , const N : usize > DecodeValue < ' a > for SequenceOf < T , N >
103+ where
104+ T : Decode < ' a > ,
105+ {
106+ type Error = T :: Error ;
107+
108+ fn decode_value < R : Reader < ' a > > ( reader : & mut R , _header : Header ) -> Result < Self , Self :: Error > {
109+ let mut sequence_of = Self :: new ( ) ;
110+
111+ while !reader. is_finished ( ) {
112+ sequence_of. add ( T :: decode ( reader) ?) ?;
113+ }
114+
115+ Ok ( sequence_of)
116+ }
117+ }
118+
119+ #[ cfg( feature = "heapless" ) ]
120+ impl < T , const N : usize > EncodeValue for SequenceOf < T , N >
121+ where
122+ T : Encode ,
123+ {
124+ fn value_len ( & self ) -> Result < Length , Error > {
125+ self . iter ( )
126+ . try_fold ( Length :: ZERO , |len, elem| len + elem. encoded_len ( ) ?)
127+ }
128+
129+ fn encode_value ( & self , writer : & mut impl Writer ) -> Result < ( ) , Error > {
130+ for elem in self . iter ( ) {
131+ elem. encode ( writer) ?;
132+ }
133+
134+ Ok ( ( ) )
135+ }
136+ }
137+
138+ #[ cfg( feature = "heapless" ) ]
139+ impl < T , const N : usize > FixedTag for SequenceOf < T , N > {
140+ const TAG : Tag = Tag :: Sequence ;
141+ }
142+
143+ #[ cfg( feature = "heapless" ) ]
144+ impl < T , const N : usize > ValueOrd for SequenceOf < T , N >
145+ where
146+ T : DerOrd ,
147+ {
148+ fn value_cmp ( & self , other : & Self ) -> Result < Ordering , Error > {
149+ iter_cmp ( self . iter ( ) , other. iter ( ) )
150+ }
151+ }
152+
153+ /// Iterator over the elements of an [`SequenceOf`].
154+ #[ cfg( feature = "heapless" ) ]
155+ #[ derive( Clone , Debug ) ]
156+ pub struct SequenceOfIter < ' a , T > {
157+ /// Inner iterator.
158+ inner : slice:: Iter < ' a , T > ,
159+ }
160+
161+ #[ cfg( feature = "heapless" ) ]
162+ impl < ' a , T : ' a > Iterator for SequenceOfIter < ' a , T > {
163+ type Item = & ' a T ;
164+
165+ fn next ( & mut self ) -> Option < & ' a T > {
166+ self . inner . next ( )
167+ }
168+
169+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
170+ self . inner . size_hint ( )
171+ }
172+ }
173+
174+ #[ cfg( feature = "heapless" ) ]
175+ impl < ' a , T : ' a > ExactSizeIterator for SequenceOfIter < ' a , T > { }
11176
12177impl < T : Encode > EncodeValue for [ T ] {
13178 fn value_len ( & self ) -> Result < Length , Error > {
@@ -24,6 +189,49 @@ impl<T: Encode> EncodeValue for [T] {
24189 }
25190}
26191
192+ #[ cfg( feature = "heapless" ) ]
193+ impl < ' a , T , const N : usize > DecodeValue < ' a > for [ T ; N ]
194+ where
195+ T : Decode < ' a > ,
196+ {
197+ type Error = T :: Error ;
198+
199+ fn decode_value < R : Reader < ' a > > ( reader : & mut R , header : Header ) -> Result < Self , Self :: Error > {
200+ let sequence_of = SequenceOf :: < T , N > :: decode_value ( reader, header) ?;
201+ sequence_of
202+ . inner
203+ . into_array ( )
204+ . map_err ( |_| reader. error ( Self :: TAG . length_error ( ) ) . into ( ) )
205+ }
206+ }
207+
208+ impl < T , const N : usize > EncodeValue for [ T ; N ]
209+ where
210+ T : Encode ,
211+ {
212+ fn value_len ( & self ) -> Result < Length , Error > {
213+ self . iter ( )
214+ . try_fold ( Length :: ZERO , |len, elem| len + elem. encoded_len ( ) ?)
215+ }
216+
217+ fn encode_value ( & self , writer : & mut impl Writer ) -> Result < ( ) , Error > {
218+ self . as_slice ( ) . encode_value ( writer)
219+ }
220+ }
221+
222+ impl < T , const N : usize > FixedTag for [ T ; N ] {
223+ const TAG : Tag = Tag :: Sequence ;
224+ }
225+
226+ impl < T , const N : usize > ValueOrd for [ T ; N ]
227+ where
228+ T : DerOrd ,
229+ {
230+ fn value_cmp ( & self , other : & Self ) -> Result < Ordering , Error > {
231+ iter_cmp ( self . iter ( ) , other. iter ( ) )
232+ }
233+ }
234+
27235#[ cfg( feature = "alloc" ) ]
28236impl < ' a , T > DecodeValue < ' a > for Vec < T >
29237where
@@ -71,3 +279,28 @@ where
71279 iter_cmp ( self . iter ( ) , other. iter ( ) )
72280 }
73281}
282+
283+ #[ cfg( all( test, feature = "heapless" ) ) ]
284+ mod tests {
285+ use super :: SequenceOf ;
286+ use crate :: ord:: DerOrd ;
287+
288+ #[ test]
289+ fn sequenceof_valueord_value_cmp ( ) {
290+ use core:: cmp:: Ordering ;
291+
292+ let arr1 = {
293+ let mut arr: SequenceOf < u16 , 2 > = SequenceOf :: new ( ) ;
294+ arr. add ( 0u16 ) . expect ( "element to be added" ) ;
295+ arr. add ( 2u16 ) . expect ( "element to be added" ) ;
296+ arr
297+ } ;
298+ let arr2 = {
299+ let mut arr: SequenceOf < u16 , 2 > = SequenceOf :: new ( ) ;
300+ arr. add ( 0u16 ) . expect ( "element to be added" ) ;
301+ arr. add ( 1u16 ) . expect ( "element to be added" ) ;
302+ arr
303+ } ;
304+ assert_eq ! ( arr1. der_cmp( & arr2) , Ok ( Ordering :: Greater ) ) ;
305+ }
306+ }
0 commit comments