@@ -118,6 +118,122 @@ where
118118 }
119119}
120120
121+ /// A codec for heapless vectors of fixed/dynamic sized elements.
122+ /// The length of the vector is encoded/decoded as a prefix using the provided length codec.
123+ /// The maximum size of the vector is determined by the const generic parameter N.
124+ ///
125+ /// # Examples
126+ /// ```rust
127+ /// use byten::{HeaplessVecCodec, Encoder, Decoder, Measurer, EncoderToVec as _, EndianCodec};
128+ ///
129+ /// let length_codec = EndianCodec::<u16>::le();
130+ /// let item_codec = EndianCodec::<u32>::le();
131+ /// let codec = HeaplessVecCodec::<_, _, 10>::new(item_codec, length_codec);
132+ ///
133+ /// let vec: heapless::Vec<u32, 10> = heapless::Vec::from_slice(&[1, 2, 3, 4]).unwrap();
134+ ///
135+ /// let encoded = codec.encode_to_heapless_vec::<20>(&vec).unwrap();
136+ /// assert_eq!(encoded.len(), 2 + 4 * 4);
137+ ///
138+ /// let mut decode_offset = 0;
139+ /// let decoded: heapless::Vec<u32, 10> = codec.decode(&encoded, &mut decode_offset).unwrap();
140+ /// assert_eq!(decoded, vec);
141+ ///
142+ /// let size = codec.measure(&vec).unwrap();
143+ /// assert_eq!(size, 2 + 4 * 4);
144+ /// ```
145+ pub struct HeaplessVecCodec < Item , Length , const N : usize > {
146+ pub item : Item ,
147+ pub length : Length ,
148+ }
149+
150+ impl < Item , Length , const N : usize > HeaplessVecCodec < Item , Length , N > {
151+ pub const fn new ( item : Item , length : Length ) -> Self {
152+ Self { item, length }
153+ }
154+ }
155+
156+ impl < ' encoded , ' decoded , ' length , Item , Length , const N : usize > crate :: Decoder < ' encoded , ' decoded >
157+ for HeaplessVecCodec < Item , Length , N >
158+ where
159+ Item : crate :: Decoder < ' encoded , ' decoded > ,
160+ Length : crate :: Decoder < ' encoded , ' length > ,
161+ Length :: Decoded : TryInto < usize > ,
162+ <Length :: Decoded as TryInto < usize > >:: Error : Into < crate :: DecodeError > ,
163+ ' encoded : ' decoded ,
164+ {
165+ type Decoded = heapless:: Vec < Item :: Decoded , N > ;
166+
167+ fn decode (
168+ & self ,
169+ encoded : & ' encoded [ u8 ] ,
170+ offset : & mut usize ,
171+ ) -> Result < Self :: Decoded , crate :: DecodeError > {
172+ let size = self
173+ . length
174+ . decode ( encoded, offset) ?
175+ . try_into ( )
176+ . map_err ( Into :: into) ?;
177+ if size > N {
178+ return Err ( crate :: DecodeError :: InvalidData ) ;
179+ }
180+ let mut vec: heapless:: Vec < Item :: Decoded , N > = heapless:: Vec :: new ( ) ;
181+ for _ in 0 ..size {
182+ let item = self . item . decode ( encoded, offset) ?;
183+ vec. push ( item)
184+ . unwrap_or_else ( |_| panic ! ( "unexpected heapless vec overflow" ) ) ;
185+ }
186+ Ok ( vec)
187+ }
188+ }
189+
190+ impl < Item , Length , const N : usize > crate :: Encoder for HeaplessVecCodec < Item , Length , N >
191+ where
192+ Length : crate :: Encoder ,
193+ Length :: Decoded : TryFrom < usize > ,
194+ <Length :: Decoded as TryFrom < usize > >:: Error : Into < crate :: EncodeError > ,
195+ Item : crate :: Encoder ,
196+ Item :: Decoded : Sized ,
197+ {
198+ type Decoded = heapless:: Vec < Item :: Decoded , N > ;
199+
200+ fn encode (
201+ & self ,
202+ decoded : & Self :: Decoded ,
203+ encoded : & mut [ u8 ] ,
204+ offset : & mut usize ,
205+ ) -> Result < ( ) , crate :: EncodeError > {
206+ let size = decoded. len ( ) ;
207+ self . length
208+ . encode ( & size. try_into ( ) . map_err ( Into :: into) ?, encoded, offset) ?;
209+ for item in decoded. iter ( ) {
210+ self . item . encode ( item, encoded, offset) ?;
211+ }
212+ Ok ( ( ) )
213+ }
214+ }
215+
216+ impl < Item , Length , const N : usize > crate :: Measurer for HeaplessVecCodec < Item , Length , N >
217+ where
218+ Length : crate :: Measurer ,
219+ Length :: Decoded : TryFrom < usize > ,
220+ <Length :: Decoded as TryFrom < usize > >:: Error : Into < crate :: error:: EncodeError > ,
221+ Item : crate :: Measurer ,
222+ Item :: Decoded : Sized ,
223+ {
224+ type Decoded = heapless:: Vec < Item :: Decoded , N > ;
225+
226+ fn measure ( & self , decoded : & Self :: Decoded ) -> Result < usize , crate :: error:: EncodeError > {
227+ let size = decoded. len ( ) ;
228+ let size_measure = self . length . measure ( & size. try_into ( ) . map_err ( Into :: into) ?) ?;
229+ let mut items_measure = 0 ;
230+ for item in decoded. iter ( ) {
231+ items_measure += self . item . measure ( item) ?;
232+ }
233+ Ok ( size_measure + items_measure)
234+ }
235+ }
236+
121237/// A codec that draws all remaining bytes from the input during decoding,
122238/// and writes all bytes during encoding.
123239///
0 commit comments