use std::fmt;
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum Error {
InvalidValue {
what: &'static str,
reason: String,
},
OutsideValidity {
material: String,
wavelength_um: f64,
shortest_um: f64,
longest_um: f64,
},
Io {
path: String,
reason: String,
},
Parse {
what: String,
reason: String,
},
}
impl Error {
pub(crate) fn invalid(what: &'static str, reason: impl Into<String>) -> Self {
Error::InvalidValue {
what,
reason: reason.into(),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::InvalidValue { what, reason } => write!(f, "invalid {what}: {reason}"),
Error::OutsideValidity {
material,
wavelength_um,
shortest_um,
longest_um,
} => write!(
f,
"{material} is only valid from {shortest_um} to {longest_um} um, not at {wavelength_um} um"
),
Error::Io { path, reason } => write!(f, "{path}: {reason}"),
Error::Parse { what, reason } => write!(f, "can't read {what}: {reason}"),
}
}
}
impl std::error::Error for Error {}
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_invalid_value_says_what_and_why() {
let e = Error::InvalidValue {
what: "wavelength",
reason: "must be positive, got -1.55 um".into(),
};
assert_eq!(
e.to_string(),
"invalid wavelength: must be positive, got -1.55 um"
);
}
#[test]
fn errors_are_std_errors() {
fn takes(_: &dyn std::error::Error) {}
takes(&Error::InvalidValue {
what: "x",
reason: "y".into(),
});
}
}