use core::num::NonZeroUsize;
use crate::display::byte_count;
use crate::fmt;
#[must_use]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct RetryRequirement(NonZeroUsize);
impl RetryRequirement {
#[must_use]
pub fn new(value: usize) -> Option<Self> {
NonZeroUsize::new(value).map(Self::from_continue_after)
}
#[must_use]
pub fn from_had_and_needed(had: usize, needed: usize) -> Option<Self> {
Self::new(needed.saturating_sub(had))
}
pub fn from_continue_after(continue_after: NonZeroUsize) -> Self {
Self(continue_after)
}
#[must_use]
pub fn continue_after(self) -> usize {
self.0.get()
}
#[must_use]
pub fn continue_after_non_zero(self) -> NonZeroUsize {
self.0
}
}
impl fmt::DisplayBase for RetryRequirement {
fn fmt(&self, w: &mut dyn fmt::Write) -> fmt::Result {
byte_count(w, self.continue_after())?;
w.write_str(" more")
}
}
impl fmt::Display for RetryRequirement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::DisplayBase::fmt(self, f)
}
}
pub trait ToRetryRequirement {
fn to_retry_requirement(&self) -> Option<RetryRequirement>;
fn is_fatal(&self) -> bool {
self.to_retry_requirement().is_none()
}
}
impl ToRetryRequirement for RetryRequirement {
fn to_retry_requirement(&self) -> Option<RetryRequirement> {
Some(*self)
}
}
impl<T> ToRetryRequirement for Option<T>
where
T: ToRetryRequirement,
{
fn to_retry_requirement(&self) -> Option<RetryRequirement> {
self.as_ref()
.and_then(ToRetryRequirement::to_retry_requirement)
}
fn is_fatal(&self) -> bool {
self.is_none()
}
}