use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseError {
pub line: usize,
pub kind: ParseErrorKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub enum ParseErrorKind {
InvalidLabel(String),
InvalidTime(String),
StartAfterEnd {
start: u64,
end: u64,
},
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "line {}: ", self.line)?;
match &self.kind {
ParseErrorKind::InvalidLabel(s) => write!(f, "invalid label: {s}"),
ParseErrorKind::InvalidTime(s) => write!(f, "invalid time value `{s}`"),
ParseErrorKind::StartAfterEnd { start, end } => {
write!(f, "start time {start} is after end time {end}")
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ScaleError {
NonFiniteFactor,
NegativeFactor,
}
impl fmt::Display for ScaleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ScaleError::NonFiniteFactor => f.write_str("scale factor must be finite"),
ScaleError::NegativeFactor => f.write_str("scale factor must not be negative"),
}
}
}
impl std::error::Error for ScaleError {}
impl std::error::Error for ParseError {}
#[derive(Debug)]
#[non_exhaustive]
pub enum ReadError {
Io(std::io::Error),
Parse(ParseError),
}
impl fmt::Display for ReadError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ReadError::Io(e) => write!(f, "i/o error: {e}"),
ReadError::Parse(e) => write!(f, "parse error: {e}"),
}
}
}
impl std::error::Error for ReadError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ReadError::Io(e) => Some(e),
ReadError::Parse(e) => Some(e),
}
}
}
impl From<std::io::Error> for ReadError {
fn from(e: std::io::Error) -> Self {
ReadError::Io(e)
}
}
impl From<ParseError> for ReadError {
fn from(e: ParseError) -> Self {
ReadError::Parse(e)
}
}