use crate::display::byte_count;
use crate::error::{CoreContext, Length, RetryRequirement, ToRetryRequirement};
use crate::fmt;
use crate::input::MaybeString;
#[must_use = "error must be handled"]
pub struct ExpectedLength<'i> {
pub(crate) len: Length,
pub(crate) context: CoreContext,
pub(crate) input: MaybeString<'i>,
}
#[allow(clippy::len_without_is_empty)]
impl<'i> ExpectedLength<'i> {
#[inline(always)]
pub fn len(&self) -> Length {
self.len
}
#[must_use]
#[inline(always)]
pub fn context(&self) -> CoreContext {
self.context
}
#[inline(always)]
pub fn input(&self) -> MaybeString<'i> {
self.input.clone()
}
}
impl<'i> fmt::Debug for ExpectedLength<'i> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExpectedLength")
.field("len", &self.len())
.field("context", &self.context().debug_for(self.input()))
.field("input", &self.input())
.finish()
}
}
impl<'i> fmt::DisplayBase for ExpectedLength<'i> {
fn fmt(&self, w: &mut dyn fmt::Write) -> fmt::Result {
w.write_str("found ")?;
byte_count(w, self.context.span.len())?;
w.write_str(" when ")?;
self.len.fmt(w)?;
w.write_str(" was expected")
}
}
impl<'i> fmt::Display for ExpectedLength<'i> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::DisplayBase::fmt(self, f)
}
}
impl<'i> ToRetryRequirement for ExpectedLength<'i> {
#[inline]
fn to_retry_requirement(&self) -> Option<RetryRequirement> {
if self.is_fatal() {
None
} else {
let had = self.context.span.len();
let needed = self.len().min();
RetryRequirement::from_had_and_needed(had, needed)
}
}
#[inline]
fn is_fatal(&self) -> bool {
self.input.is_bound() || self.len().max().is_some()
}
}