use std::{error::Error as StdError, fmt, io::Error as IoError, num::ParseFloatError};
pub type ParseResult<T> = Result<T, ParseError>;
#[derive(Debug)]
#[allow(clippy::upper_case_acronyms)]
pub enum ParseError {
IoError(IoError),
IncorrectFileHeader,
BadLine,
InvalidCurvePoints,
InvalidDecimalNumber,
InvalidMode,
MissingField(&'static str),
UnknownHitObjectKind,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::IoError(_) => f.write_str("IO error"),
Self::IncorrectFileHeader => {
write!(f, "expected `osu file format v` at file begin")
}
Self::BadLine => f.write_str("line not in `Key:Value` pattern"),
Self::InvalidCurvePoints => f.write_str("invalid curve point"),
Self::InvalidDecimalNumber => f.write_str("invalid float number"),
Self::InvalidMode => f.write_str("invalid mode"),
Self::MissingField(field) => write!(f, "missing field `{field}`"),
Self::UnknownHitObjectKind => f.write_str("unsupported hitobject kind"),
}
}
}
impl StdError for ParseError {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
Self::IoError(inner) => Some(inner),
Self::IncorrectFileHeader => None,
Self::BadLine => None,
Self::InvalidCurvePoints => None,
Self::InvalidDecimalNumber => None,
Self::InvalidMode => None,
Self::MissingField(_) => None,
Self::UnknownHitObjectKind => None,
}
}
}
impl From<IoError> for ParseError {
fn from(other: IoError) -> Self {
Self::IoError(other)
}
}
impl From<ParseFloatError> for ParseError {
fn from(_: ParseFloatError) -> Self {
Self::InvalidDecimalNumber
}
}