pub fn combine_op_hashes<
T: IntoIterator<Item = I>,
I: Clone + Into<bytes::Bytes>,
>(
hashes: T,
) -> bytes::BytesMut {
let mut hashes = hashes.into_iter().peekable();
let mut out = if let Some(first) = hashes.peek() {
bytes::BytesMut::zeroed(first.clone().into().len())
} else {
return bytes::BytesMut::new();
};
for hash in hashes {
combine_hashes(&mut out, hash.into());
}
out
}
pub fn combine_hashes(into: &mut bytes::BytesMut, other: bytes::Bytes) {
if into.is_empty() && !other.is_empty() {
into.extend_from_slice(&other);
return;
}
if into.len() != other.len() {
panic!(
"Refusing to combine hashes of different lengths ({} != {}), this data should have been rejected by the host",
into.len(),
other.len()
);
}
for (into_byte, other_byte) in into.iter_mut().zip(other.iter()) {
*into_byte ^= other_byte;
}
}