1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4
5 use crate::{MlsDecode, MlsEncode, MlsSize, VarInt};
6
7 use alloc::vec::Vec;
8
mls_encoded_len<T>(iter: impl Iterator<Item = T>) -> usize where T: MlsSize,9 pub fn mls_encoded_len<T>(iter: impl Iterator<Item = T>) -> usize
10 where
11 T: MlsSize,
12 {
13 let len = iter.map(|x| x.mls_encoded_len()).sum::<usize>();
14
15 let header_length = VarInt::try_from(len).unwrap_or(VarInt(0)).mls_encoded_len();
16
17 header_length + len
18 }
19
20 #[cfg(feature = "preallocate")]
mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error> where I: IntoIterator + Clone, I::Item: MlsEncode,21 pub fn mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error>
22 where
23 I: IntoIterator + Clone,
24 I::Item: MlsEncode,
25 {
26 let len = iter
27 .clone()
28 .into_iter()
29 .map(|x| x.mls_encoded_len())
30 .sum::<usize>();
31
32 let header_length = VarInt::try_from(len)?;
33 header_length.mls_encode(writer)?;
34
35 writer.reserve(len);
36
37 iter.into_iter().try_for_each(|x| x.mls_encode(writer))?;
38
39 Ok(())
40 }
41
42 #[cfg(not(feature = "preallocate"))]
mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error> where I: IntoIterator + Clone, I::Item: MlsEncode,43 pub fn mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error>
44 where
45 I: IntoIterator + Clone,
46 I::Item: MlsEncode,
47 {
48 let mut buffer = Vec::new();
49
50 iter.into_iter()
51 .try_for_each(|x| x.mls_encode(&mut buffer))?;
52
53 let len = VarInt::try_from(buffer.len())?;
54
55 len.mls_encode(writer)?;
56 writer.extend(buffer);
57
58 Ok(())
59 }
60
mls_decode_collection<T, F>(reader: &mut &[u8], item_decode: F) -> Result<T, crate::Error> where F: Fn(&mut &[u8]) -> Result<T, crate::Error>,61 pub fn mls_decode_collection<T, F>(reader: &mut &[u8], item_decode: F) -> Result<T, crate::Error>
62 where
63 F: Fn(&mut &[u8]) -> Result<T, crate::Error>,
64 {
65 let (mut data, rest) = mls_decode_split_on_collection(reader)?;
66
67 let items = item_decode(&mut data)?;
68
69 *reader = rest;
70
71 Ok(items)
72 }
73
mls_decode_split_on_collection<'b>( reader: &mut &'b [u8], ) -> Result<(&'b [u8], &'b [u8]), crate::Error>74 pub fn mls_decode_split_on_collection<'b>(
75 reader: &mut &'b [u8],
76 ) -> Result<(&'b [u8], &'b [u8]), crate::Error> {
77 let len = VarInt::mls_decode(reader)?.0 as usize;
78
79 if len > reader.len() {
80 return Err(crate::Error::UnexpectedEOF);
81 }
82
83 Ok(reader.split_at(len))
84 }
85