// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright by contributors to this project. // SPDX-License-Identifier: (Apache-2.0 OR MIT) use crate::{MlsDecode, MlsEncode, MlsSize, VarInt}; use alloc::vec::Vec; pub fn mls_encoded_len<T>(iter: impl Iterator<Item = T>) -> usize where T: MlsSize, { let len = iter.map(|x| x.mls_encoded_len()).sum::<usize>(); let header_length = VarInt::try_from(len).unwrap_or(VarInt(0)).mls_encoded_len(); header_length + len } #[cfg(feature = "preallocate")] pub fn mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error> where I: IntoIterator + Clone, I::Item: MlsEncode, { let len = iter .clone() .into_iter() .map(|x| x.mls_encoded_len()) .sum::<usize>(); let header_length = VarInt::try_from(len)?; header_length.mls_encode(writer)?; writer.reserve(len); iter.into_iter().try_for_each(|x| x.mls_encode(writer))?; Ok(()) } #[cfg(not(feature = "preallocate"))] pub fn mls_encode<I>(iter: I, writer: &mut Vec<u8>) -> Result<(), crate::Error> where I: IntoIterator + Clone, I::Item: MlsEncode, { let mut buffer = Vec::new(); iter.into_iter() .try_for_each(|x| x.mls_encode(&mut buffer))?; let len = VarInt::try_from(buffer.len())?; len.mls_encode(writer)?; writer.extend(buffer); Ok(()) } pub fn mls_decode_collection<T, F>(reader: &mut &[u8], item_decode: F) -> Result<T, crate::Error> where F: Fn(&mut &[u8]) -> Result<T, crate::Error>, { let (mut data, rest) = mls_decode_split_on_collection(reader)?; let items = item_decode(&mut data)?; *reader = rest; Ok(items) } pub fn mls_decode_split_on_collection<'b>( reader: &mut &'b [u8], ) -> Result<(&'b [u8], &'b [u8]), crate::Error> { let len = VarInt::mls_decode(reader)?.0 as usize; if len > reader.len() { return Err(crate::Error::UnexpectedEOF); } Ok(reader.split_at(len)) }