1pub trait Length {
32 fn length(&self) -> usize;
33}
34
35pub trait Encode: Length {
84 fn encode(&self, dst: &mut [u8]) -> usize;
88}
89
90#[doc(hidden)]
91pub trait EncodeExt: Encode {
92 fn encode_move(&self, dst: &mut [u8], size: usize) -> usize {
93 size + self.encode(&mut dst[size..])
94 }
95}
96
97impl<T: Encode> EncodeExt for T {}
98
99impl<T: Length> Length for Option<T> {
100 fn length(&self) -> usize {
101 self.as_ref().map(Length::length).unwrap_or(0)
102 }
103}
104
105impl<T: Length> Length for &[T] {
106 fn length(&self) -> usize {
107 self.iter().map(Length::length).sum()
108 }
109}
110
111#[cfg(any(test, feature = "alloc"))]
112#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
113impl<T: Length> Length for alloc::vec::Vec<T> {
114 fn length(&self) -> usize {
115 self.as_slice().length()
116 }
117}
118
119impl<T: Length, const N: usize> Length for heapless::vec::Vec<T, N> {
120 fn length(&self) -> usize {
121 self.as_slice().length()
122 }
123}
124
125impl<T: Encode> Encode for Option<T> {
126 fn encode(&self, dst: &mut [u8]) -> usize {
127 self.as_ref().map(|item| item.encode(dst)).unwrap_or(0)
128 }
129}
130
131impl<T: Encode> Encode for &[T] {
132 fn encode(&self, dst: &mut [u8]) -> usize {
133 self.iter()
134 .fold(0, |acc, item| acc + item.encode(&mut dst[acc..]))
135 }
136}
137
138#[cfg(any(test, feature = "alloc"))]
139#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
140impl<T: Encode> Encode for alloc::vec::Vec<T> {
141 fn encode(&self, dst: &mut [u8]) -> usize {
142 self.as_slice().encode(dst)
143 }
144}
145
146impl<T: Encode, const N: usize> Encode for heapless::vec::Vec<T, N> {
147 fn encode(&self, dst: &mut [u8]) -> usize {
148 self.as_slice().encode(dst)
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155
156 mod owned {
157 use crate::types::owned::{
158 AnyOctetString, COctetString, EmptyOrFullCOctetString, OctetString,
159 };
160
161 use super::*;
162
163 #[test]
164 fn length_option() {
165 let value: Option<u8> = Some(0u8);
166 assert_eq!(value.length(), 1);
167
168 let value: Option<u8> = None;
169 assert_eq!(value.length(), 0);
170 }
171
172 #[test]
173 fn length_vec() {
174 let values: alloc::vec::Vec<u8> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
175 assert_eq!(values.length(), 10);
176
177 let values: alloc::vec::Vec<u16> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
178 assert_eq!(values.length(), 20);
179
180 let values: alloc::vec::Vec<u32> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
181 assert_eq!(values.length(), 40);
182
183 let values = alloc::vec![AnyOctetString::new(b"Hello"), AnyOctetString::new(b"World")];
184 assert_eq!(values.length(), 10);
185
186 let values = alloc::vec![
187 COctetString::<1, 6>::new(b"Hello\0").unwrap(),
188 COctetString::<1, 6>::new(b"World\0").unwrap(),
189 ];
190 assert_eq!(values.length(), 12);
191
192 let values = alloc::vec![
193 EmptyOrFullCOctetString::<6>::new(b"Hello\0").unwrap(),
194 EmptyOrFullCOctetString::<6>::new(b"World\0").unwrap(),
195 ];
196 assert_eq!(values.length(), 12);
197
198 let values = alloc::vec![
199 OctetString::<0, 5>::new(b"Hello").unwrap(),
200 OctetString::<0, 5>::new(b"World").unwrap(),
201 ];
202 assert_eq!(values.length(), 10);
203 }
204
205 #[test]
206 fn encode_option() {
207 let buf = &mut [0u8; 1024];
208
209 let value: Option<u8> = Some(0u8);
210 assert!(buf.len() >= value.length());
211
212 let size = value.encode(buf);
213
214 assert_eq!(size, 1);
215 assert_eq!(&buf[..size], &[0]);
216
217 let value: Option<u8> = None;
218 assert!(buf.len() >= value.length());
219
220 let size = value.encode(buf);
221
222 assert_eq!(size, 0);
223 }
224
225 #[test]
226 fn encode_vec() {
227 let buf = &mut [0u8; 1024];
228
229 let values: alloc::vec::Vec<u8> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
230 assert!(buf.len() >= values.length());
231
232 let size = values.encode(buf);
233
234 assert_eq!(size, 10);
235 assert_eq!(&buf[..size], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
236
237 let values: alloc::vec::Vec<u16> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
238 assert!(buf.len() >= values.length());
239
240 let size = values.encode(buf);
241
242 assert_eq!(size, 20);
243 assert_eq!(
244 &buf[..size],
245 &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9]
246 );
247
248 let values: alloc::vec::Vec<u32> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
249 assert!(buf.len() >= values.length());
250
251 let size = values.encode(buf);
252 assert_eq!(size, 40);
253
254 assert_eq!(
255 &buf[..size],
256 &[
257 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0,
258 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9
259 ]
260 );
261
262 let values = alloc::vec![AnyOctetString::new(b"Hello"), AnyOctetString::new(b"World")];
263 assert!(buf.len() >= values.length());
264
265 let size = values.encode(buf);
266
267 assert_eq!(size, 10);
268 assert_eq!(&buf[..size], b"HelloWorld");
269
270 let values = alloc::vec![
271 COctetString::<1, 6>::new(b"Hello\0").unwrap(),
272 COctetString::<1, 6>::new(b"World\0").unwrap(),
273 ];
274 assert!(buf.len() >= values.length());
275
276 let size = values.encode(buf);
277
278 assert_eq!(size, 12);
279 assert_eq!(&buf[..size], b"Hello\0World\0");
280
281 let values = alloc::vec![
282 EmptyOrFullCOctetString::<6>::new(b"Hello\0").unwrap(),
283 EmptyOrFullCOctetString::<6>::new(b"World\0").unwrap(),
284 ];
285 assert!(buf.len() >= values.length());
286
287 let size = values.encode(buf);
288
289 assert_eq!(size, 12);
290 assert_eq!(&buf[..size], b"Hello\0World\0");
291
292 let values = alloc::vec![
293 OctetString::<0, 5>::new(b"Hello").unwrap(),
294 OctetString::<0, 5>::new(b"World").unwrap(),
295 ];
296 assert!(buf.len() >= values.length());
297
298 let size = values.encode(buf);
299
300 assert_eq!(size, 10);
301 assert_eq!(&buf[..size], b"HelloWorld");
302 }
303 }
304}