use std::error::Error;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;
#[derive(Debug)]
pub struct ParseError {
pub src: String,
pub index: Option<usize>,
pub kind: ErrorKind,
}
impl ParseError {
pub(crate) fn new(src: &str, kind: ErrorKind) -> Self {
Self { src: src.into(), index: None, kind }
}
pub(crate) fn at_index(mut self, ix: usize) -> Self {
self.index = Some(ix);
self
}
}
impl Display for ParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(
f,
"{}\n{}\n{}",
self.src,
match self.index {
Some(ix) => format!("{}^-----", " ".repeat(ix)),
None => String::new(),
},
self.kind
)
}
}
impl Error for ParseError {}
#[derive(Debug)]
#[non_exhaustive]
pub enum ErrorKind {
Ambiguous,
IncompleteDate,
InputTooLong,
InputTooShort,
InvalidFormat,
MissingDate,
MissingTime,
Unexpected,
}
impl Display for ErrorKind {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{}", match self {
Self::Ambiguous => "Parsing succeeded, but the final date was ambiguous",
Self::IncompleteDate => "Date specified, but could not determine year, month, and day",
Self::InputTooLong => "Parsing finished, but input remains",
Self::InputTooShort => "Input terminated unexpectedly before parsing finished",
Self::InvalidFormat => "Could not parse format string",
Self::MissingDate => "Parsing successful, but no date found",
Self::MissingTime => "Parsing successful, but no time found",
Self::Unexpected => "Input does not conform to format string",
})
}
}