use super::{FragmentationError, Fragmenter, encode_fragment_payload};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FragmentParts {
id: u32,
correlation_id: Option<u64>,
payload: Vec<u8>,
}
impl FragmentParts {
#[must_use]
pub fn new(id: u32, correlation_id: Option<u64>, payload: Vec<u8>) -> Self {
Self {
id,
correlation_id,
payload,
}
}
#[must_use]
pub const fn id(&self) -> u32 { self.id }
#[must_use]
pub const fn correlation_id(&self) -> Option<u64> { self.correlation_id }
#[must_use]
pub fn into_payload(self) -> Vec<u8> { self.payload }
}
pub trait Fragmentable: Send + Sync + 'static + Sized {
fn into_fragment_parts(self) -> FragmentParts;
fn from_fragment_parts(parts: FragmentParts) -> Self;
}
pub fn fragment_packet<E: Fragmentable>(
fragmenter: &Fragmenter,
packet: E,
) -> Result<Vec<E>, FragmentationError> {
let parts = packet.into_fragment_parts();
let id = parts.id();
let correlation = parts.correlation_id();
let payload = parts.into_payload();
let batch = fragmenter.fragment_bytes(&payload)?;
if !batch.is_fragmented() {
return Ok(vec![E::from_fragment_parts(FragmentParts::new(
id,
correlation,
payload,
))]);
}
let mut frames = Vec::with_capacity(batch.len());
for fragment in batch {
let (header, payload) = fragment.into_parts();
let encoded = encode_fragment_payload(header, &payload)?;
frames.push(E::from_fragment_parts(FragmentParts::new(
id,
correlation,
encoded,
)));
}
Ok(frames)
}