use crate::encoding::{Serialize, WriteCursor};
use alloc::vec::Vec;
use canadensis_core::{nb, OutOfMemoryError};
use core::iter;
use fallible_collections::{FallibleVec, TryReserveError};
const STACK_THRESHOLD: usize = 64;
pub(crate) fn do_serialize<T, F, R, E>(payload: &T, operation: F) -> nb::Result<R, E>
where
T: Serialize,
F: FnOnce(&[u8]) -> nb::Result<R, E>,
E: From<OutOfMemoryError>,
{
let payload_bytes = payload.size_bits().div_ceil(8);
if payload_bytes > STACK_THRESHOLD {
let mut bytes: Vec<u8> = FallibleVec::try_with_capacity(payload_bytes)
.map_err(|e: TryReserveError| nb::Error::Other(E::from(OutOfMemoryError::from(e))))?;
bytes.extend(iter::repeat_n(0, payload_bytes));
payload.serialize(&mut WriteCursor::new(&mut bytes));
operation(&bytes)
} else {
let mut bytes = [0u8; STACK_THRESHOLD];
let bytes = &mut bytes[..payload_bytes];
payload.serialize(&mut WriteCursor::new(bytes));
operation(bytes)
}
}