use crate::field::{Elem, FieldBuffer};
pub fn pack<F: FieldBuffer>(dst: &mut [u8], elems: &[Elem<F>]) {
let expected = elems
.len()
.checked_mul(F::BYTES)
.expect("pack: buffer geometry overflows");
assert_eq!(
dst.len(),
expected,
"pack: dst is {} bytes but {} {} elements need {expected}",
dst.len(),
elems.len(),
F::NAME,
);
for (bytes, &elem) in dst.chunks_exact_mut(F::BYTES).zip(elems) {
F::encode(bytes, elem);
}
}
pub fn unpack<F: FieldBuffer>(dst: &mut [Elem<F>], src: &[u8]) {
let expected = dst
.len()
.checked_mul(F::BYTES)
.expect("unpack: buffer geometry overflows");
assert_eq!(
src.len(),
expected,
"unpack: src is {} bytes but dst holds {} {} elements ({expected} bytes)",
src.len(),
dst.len(),
F::NAME,
);
for (elem, bytes) in dst.iter_mut().zip(src.chunks_exact(F::BYTES)) {
*elem = F::decode(bytes);
}
}
#[cfg(feature = "alloc")]
#[must_use]
pub fn pack_to_vec<F: FieldBuffer>(elems: &[Elem<F>]) -> alloc::vec::Vec<u8> {
let len = elems
.len()
.checked_mul(F::BYTES)
.expect("pack_to_vec: buffer geometry overflows");
let mut bytes = alloc::vec![0; len];
pack::<F>(&mut bytes, elems);
bytes
}
#[cfg(feature = "alloc")]
#[must_use]
pub fn unpack_to_vec<F: FieldBuffer>(src: &[u8]) -> alloc::vec::Vec<Elem<F>> {
assert!(
src.len().is_multiple_of(F::BYTES),
"unpack_to_vec: src is {} bytes, not a whole number of {} elements",
src.len(),
F::NAME,
);
let len = src.len() / F::BYTES;
let mut elems = alloc::vec![Elem::<F>::ZERO; len];
unpack::<F>(&mut elems, src);
elems
}