#[derive(Debug)]
#[non_exhaustive]
pub enum ParseError {
TooLong,
MissingField(std::borrow::Cow<'static, str>),
InvalidField(std::borrow::Cow<'static, str>, Box<dyn std::error::Error + Send + Sync>),
InvalidLine(InvalidString),
InvalidNick(InvalidString),
InvalidUser(InvalidString),
InvalidHost(InvalidString),
InvalidKind(InvalidString),
}
impl std::fmt::Display for ParseError {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ParseError::TooLong => write!(fmt, "message is too long"),
ParseError::MissingField(f) => write!(fmt, "missing field {f}"),
ParseError::InvalidField(f, e) => write!(fmt, "invalid field {f}: {e}"),
ParseError::InvalidLine(e) => write!(fmt, "invalid line: {e}"),
ParseError::InvalidNick(e) => write!(fmt, "invalid source nickname: {e}"),
ParseError::InvalidUser(e) => write!(fmt, "invalid source username: {e}"),
ParseError::InvalidHost(e) => write!(fmt, "invalid source hostname: {e}"),
ParseError::InvalidKind(e) => write!(fmt, "invalid message kind: {e}"),
}
}
}
impl std::error::Error for ParseError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ParseError::InvalidField(_, e) => Some(e.as_ref()),
ParseError::InvalidLine(ref e) => Some(e),
ParseError::InvalidNick(ref e) => Some(e),
ParseError::InvalidUser(ref e) => Some(e),
ParseError::InvalidHost(ref e) => Some(e),
ParseError::InvalidKind(ref e) => Some(e),
_ => None,
}
}
}
impl From<ParseError> for std::io::Error {
fn from(value: ParseError) -> Self {
std::io::Error::new(std::io::ErrorKind::InvalidData, value)
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum InvalidString {
Empty,
Colon,
Byte(u8),
}
impl std::fmt::Display for InvalidString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
InvalidString::Empty => write!(f, "empty substring"),
InvalidString::Colon => write!(f, "substring begins with colon"),
InvalidString::Byte(b) => write!(f, "invalid byte '{}'", b.escape_ascii()),
}
}
}
impl std::error::Error for InvalidString {}
impl From<std::convert::Infallible> for InvalidString {
fn from(value: std::convert::Infallible) -> Self {
match value {}
}
}
impl From<InvalidString> for std::io::Error {
fn from(value: InvalidString) -> Self {
std::io::Error::new(std::io::ErrorKind::InvalidData, value)
}
}