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(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(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(feature = "alloc")]
153#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
154pub mod owned {
155 use bytes::BytesMut;
158
159 use super::Length;
160
161 pub trait Encode: Length {
208 fn encode(&self, dst: &mut BytesMut);
212 }
213
214 impl<T: Encode> Encode for Option<T> {
215 fn encode(&self, dst: &mut BytesMut) {
216 if let Some(item) = self.as_ref() {
217 item.encode(dst)
218 }
219 }
220 }
221
222 impl<T: Encode> Encode for &[T] {
223 fn encode(&self, dst: &mut BytesMut) {
224 for item in *self {
225 item.encode(dst);
226 }
227 }
228 }
229
230 impl<T: Encode> Encode for alloc::vec::Vec<T> {
231 fn encode(&self, dst: &mut BytesMut) {
232 self.as_slice().encode(dst)
233 }
234 }
235
236 impl<T: Encode, const N: usize> Encode for heapless::vec::Vec<T, N> {
237 fn encode(&self, dst: &mut BytesMut) {
238 self.as_slice().encode(dst)
239 }
240 }
241}
242
243#[cfg(test)]
244mod tests {
245 mod borrowed {
246
247 use super::super::*;
248
249 #[test]
250 fn length_option() {
251 let value: Option<u8> = Some(0u8);
252 assert_eq!(value.length(), 1);
253
254 let value: Option<u8> = None;
255 assert_eq!(value.length(), 0);
256 }
257
258 #[test]
259 fn encode_option() {
260 let buf = &mut [0u8; 1024];
261 let value: Option<u8> = Some(0u8);
262 assert!(buf.len() >= value.length());
263 let size = value.encode(buf);
264 assert_eq!(size, 1);
265 assert_eq!(&buf[..size], &[0]);
266
267 let value: Option<u8> = None;
268 assert!(buf.len() >= value.length());
269 let size = value.encode(buf);
270 assert_eq!(size, 0);
271 }
272
273 #[cfg(feature = "alloc")]
274 mod owned_extensions {
275 use crate::types::borrowed::{
276 AnyOctetString, COctetString, EmptyOrFullCOctetString, OctetString,
277 };
278
279 use super::*;
280
281 #[test]
282 fn length_vec() {
283 let values: alloc::vec::Vec<u8> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
284 assert_eq!(values.length(), 10);
285
286 let values: alloc::vec::Vec<u16> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
287 assert_eq!(values.length(), 20);
288
289 let values: alloc::vec::Vec<u32> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
290 assert_eq!(values.length(), 40);
291
292 let values =
293 alloc::vec![AnyOctetString::new(b"Hello"), AnyOctetString::new(b"World")];
294 assert_eq!(values.length(), 10);
295
296 let values = alloc::vec![
297 COctetString::<1, 6>::new(b"Hello\0").unwrap(),
298 COctetString::<1, 6>::new(b"World\0").unwrap(),
299 ];
300 assert_eq!(values.length(), 12);
301
302 let values = alloc::vec![
303 EmptyOrFullCOctetString::<6>::new(b"Hello\0").unwrap(),
304 EmptyOrFullCOctetString::<6>::new(b"World\0").unwrap(),
305 ];
306 assert_eq!(values.length(), 12);
307
308 let values = alloc::vec![
309 OctetString::<0, 5>::new(b"Hello").unwrap(),
310 OctetString::<0, 5>::new(b"World").unwrap(),
311 ];
312 assert_eq!(values.length(), 10);
313 }
314
315 #[test]
316 fn encode_vec() {
317 let buf = &mut [0u8; 1024];
318
319 let values: alloc::vec::Vec<u8> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
320 assert!(buf.len() >= values.length());
321 let size = values.encode(buf);
322 assert_eq!(size, 10);
323 assert_eq!(&buf[..size], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
324
325 let values: alloc::vec::Vec<u16> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
326 assert!(buf.len() >= values.length());
327 let size = values.encode(buf);
328 assert_eq!(size, 20);
329 assert_eq!(
330 &buf[..size],
331 &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9]
332 );
333
334 let values: alloc::vec::Vec<u32> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
335 assert!(buf.len() >= values.length());
336 let size = values.encode(buf);
337 assert_eq!(size, 40);
338 assert_eq!(
339 &buf[..size],
340 &[
341 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,
342 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9
343 ]
344 );
345
346 let values =
347 alloc::vec![AnyOctetString::new(b"Hello"), AnyOctetString::new(b"World")];
348 assert!(buf.len() >= values.length());
349 let size = values.encode(buf);
350 assert_eq!(size, 10);
351 assert_eq!(&buf[..size], b"HelloWorld");
352
353 let values = alloc::vec![
354 COctetString::<1, 6>::new(b"Hello\0").unwrap(),
355 COctetString::<1, 6>::new(b"World\0").unwrap(),
356 ];
357 assert!(buf.len() >= values.length());
358 let size = values.encode(buf);
359 assert_eq!(size, 12);
360 assert_eq!(&buf[..size], b"Hello\0World\0");
361
362 let values = alloc::vec![
363 EmptyOrFullCOctetString::<6>::new(b"Hello\0").unwrap(),
364 EmptyOrFullCOctetString::<6>::new(b"World\0").unwrap(),
365 ];
366 assert!(buf.len() >= values.length());
367 let size = values.encode(buf);
368 assert_eq!(size, 12);
369 assert_eq!(&buf[..size], b"Hello\0World\0");
370
371 let values = alloc::vec![
372 OctetString::<0, 5>::new(b"Hello").unwrap(),
373 OctetString::<0, 5>::new(b"World").unwrap(),
374 ];
375 assert!(buf.len() >= values.length());
376 let size = values.encode(buf);
377 assert_eq!(size, 10);
378 assert_eq!(&buf[..size], b"HelloWorld");
379 }
380 }
381 }
382
383 #[cfg(feature = "alloc")]
384 mod owned {
385 use bytes::BytesMut;
386
387 use crate::types::owned::{
388 AnyOctetString, COctetString, EmptyOrFullCOctetString, OctetString,
389 };
390
391 use super::super::{Length, owned::Encode};
392
393 #[test]
394 fn encode_option() {
395 let mut buf = BytesMut::with_capacity(1024);
396 let value: Option<u8> = Some(0u8);
397 assert!(buf.capacity() >= value.length());
398 value.encode(&mut buf);
399 assert_eq!(buf.len(), 1);
400 assert_eq!(&buf[..1], &[0]);
401
402 let mut buf = BytesMut::with_capacity(1024);
403 let value: Option<u8> = None;
404 assert!(buf.capacity() >= value.length());
405 value.encode(&mut buf);
406 assert_eq!(buf.len(), 0);
407 }
408
409 #[test]
410 fn encode_vec() {
411 let mut buf = BytesMut::with_capacity(1024);
412 let values: alloc::vec::Vec<u8> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
413 assert!(buf.capacity() >= values.length());
414 values.encode(&mut buf);
415 assert_eq!(buf.len(), 10);
416 assert_eq!(&buf[..10], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
417
418 let mut buf = BytesMut::with_capacity(1024);
419 let values: alloc::vec::Vec<u16> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
420 assert!(buf.capacity() >= values.length());
421 values.encode(&mut buf);
422 assert_eq!(buf.len(), 20);
423 assert_eq!(
424 &buf[..20],
425 &[0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9]
426 );
427
428 let mut buf = BytesMut::with_capacity(1024);
429 let values: alloc::vec::Vec<u32> = alloc::vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
430 assert!(buf.capacity() >= values.length());
431 values.encode(&mut buf);
432 assert_eq!(buf.len(), 40);
433 assert_eq!(
434 &buf[..40],
435 &[
436 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,
437 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 9
438 ]
439 );
440
441 let mut buf = BytesMut::with_capacity(1024);
442 let values = alloc::vec![
443 AnyOctetString::from_static_slice(b"Hello"),
444 AnyOctetString::from_static_slice(b"World")
445 ];
446 assert!(buf.capacity() >= values.length());
447 values.encode(&mut buf);
448 assert_eq!(buf.len(), 10);
449 assert_eq!(&buf[..10], b"HelloWorld");
450
451 let mut buf = BytesMut::with_capacity(1024);
452 let values = alloc::vec![
453 COctetString::<1, 6>::from_static_slice(b"Hello\0").unwrap(),
454 COctetString::<1, 6>::from_static_slice(b"World\0").unwrap(),
455 ];
456 assert!(buf.capacity() >= values.length());
457 values.encode(&mut buf);
458 assert_eq!(buf.len(), 12);
459 assert_eq!(&buf[..12], b"Hello\0World\0");
460
461 let mut buf = BytesMut::with_capacity(1024);
462 let values = alloc::vec![
463 EmptyOrFullCOctetString::<6>::from_static_slice(b"Hello\0").unwrap(),
464 EmptyOrFullCOctetString::<6>::from_static_slice(b"World\0").unwrap(),
465 ];
466 assert!(buf.capacity() >= values.length());
467 values.encode(&mut buf);
468 assert_eq!(buf.len(), 12);
469 assert_eq!(&buf[..12], b"Hello\0World\0");
470
471 let mut buf = BytesMut::with_capacity(1024);
472 let values = alloc::vec![
473 OctetString::<0, 5>::from_static_slice(b"Hello").unwrap(),
474 OctetString::<0, 5>::from_static_slice(b"World").unwrap(),
475 ];
476 assert!(buf.capacity() >= values.length());
477 values.encode(&mut buf);
478 assert_eq!(buf.len(), 10);
479 assert_eq!(&buf[..10], b"HelloWorld");
480 }
481 }
482}