use super::{FragmentError, FragmentHeader, FragmentIndex, FragmentStatus, MessageId};
#[derive(Clone, Debug)]
pub struct FragmentSeries {
message_id: MessageId,
next_index: FragmentIndex,
complete: bool,
}
impl FragmentSeries {
#[must_use]
pub const fn new(message_id: MessageId) -> Self {
Self {
message_id,
next_index: FragmentIndex::zero(),
complete: false,
}
}
#[must_use]
pub const fn message_id(&self) -> MessageId { self.message_id }
#[must_use]
pub const fn is_complete(&self) -> bool { self.complete }
pub fn accept(&mut self, fragment: FragmentHeader) -> Result<FragmentStatus, FragmentError> {
if fragment.message_id() != self.message_id {
return Err(FragmentError::MessageMismatch {
expected: self.message_id,
found: fragment.message_id(),
});
}
if fragment.fragment_index() < self.next_index {
return Ok(FragmentStatus::Duplicate);
}
if self.complete {
return Err(FragmentError::SeriesComplete);
}
if fragment.fragment_index() > self.next_index {
return Err(FragmentError::IndexMismatch {
expected: self.next_index,
found: fragment.fragment_index(),
});
}
let next_index = fragment.fragment_index().checked_increment();
if fragment.is_last_fragment() {
self.complete = true;
if let Some(incremented) = next_index {
self.next_index = incremented;
}
return Ok(FragmentStatus::Complete);
}
let Some(incremented) = next_index else {
return Err(FragmentError::IndexOverflow {
last: fragment.fragment_index(),
});
};
self.next_index = incremented;
Ok(FragmentStatus::Incomplete)
}
}
impl FragmentSeries {
#[doc(hidden)]
pub fn force_next_index_for_tests(&mut self, next: FragmentIndex) { self.next_index = next; }
}