98 lines
2.9 KiB
Rust
98 lines
2.9 KiB
Rust
#![allow(
|
|||
|
|
clippy::cast_possible_truncation,
|
||
|
|
clippy::cast_sign_loss,
|
||
|
|
clippy::cast_precision_loss,
|
||
|
|
clippy::cast_possible_wrap
|
||
|
|
)]
|
||
|
|
|
||
|
|
use std::fmt;
|
||
|
|
|
||
|
|
/// Unified error type for the zesdex codebase.
|
||
|
|
#[derive(Debug)]
|
||
|
|
pub enum Error {
|
||
|
|
/// Wraps an I/O error.
|
||
|
|
Io(std::io::Error),
|
||
|
|
/// Wraps a JSON serialization/deserialization error.
|
||
|
|
Serde(serde_json::Error),
|
||
|
|
/// A generic parse failure with a message.
|
||
|
|
Parse(String),
|
||
|
|
/// A resource was not found.
|
||
|
|
NotFound(String),
|
||
|
|
/// Invalid input was provided.
|
||
|
|
InvalidInput(String),
|
||
|
|
/// The session is locked and cannot be accessed.
|
||
|
|
SessionLocked,
|
||
|
|
}
|
||
|
|
|
||
|
|
impl fmt::Display for Error {
|
||
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||
|
|
match self {
|
||
|
|
Self::Io(e) => write!(f, "I/O error: {e}"),
|
||
|
|
Self::Serde(e) => write!(f, "serialization error: {e}"),
|
||
|
|
Self::Parse(msg) => write!(f, "parse error: {msg}"),
|
||
|
|
Self::NotFound(resource) => write!(f, "not found: {resource}"),
|
||
|
|
Self::InvalidInput(msg) => write!(f, "invalid input: {msg}"),
|
||
|
|
Self::SessionLocked => write!(f, "session is locked"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl std::error::Error for Error {
|
||
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||
|
|
match self {
|
||
|
|
Self::Io(e) => Some(e),
|
||
|
|
Self::Serde(e) => Some(e),
|
||
|
|
Self::Parse(_) | Self::NotFound(_) | Self::InvalidInput(_) | Self::SessionLocked => {
|
||
|
|
None
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// From conversions
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
impl From<std::io::Error> for Error {
|
||
|
|
fn from(e: std::io::Error) -> Self {
|
||
|
|
Self::Io(e)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl From<serde_json::Error> for Error {
|
||
|
|
fn from(e: serde_json::Error) -> Self {
|
||
|
|
Self::Serde(e)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Note: anyhow already provides `From<E> for anyhow::Error` for all
|
||
|
|
// `E: std::error::Error + Send + Sync + 'static`, which our `Error` satisfies.
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Type alias
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
/// Convenience alias for `Result<T, zesdex_utils::Error>`.
|
||
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
||
|
|
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
// Additional impls
|
||
|
|
// ---------------------------------------------------------------------------
|
||
|
|
|
||
|
|
impl Error {
|
||
|
|
/// Create a `Parse` error.
|
||
|
|
pub fn parse(msg: impl Into<String>) -> Self {
|
||
|
|
Self::Parse(msg.into())
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Create a `NotFound` error.
|
||
|
|
pub fn not_found(resource: impl Into<String>) -> Self {
|
||
|
|
Self::NotFound(resource.into())
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Create an `InvalidInput` error.
|
||
|
|
pub fn invalid_input(msg: impl Into<String>) -> Self {
|
||
|
|
Self::InvalidInput(msg.into())
|
||
|
|
}
|
||
|
|
}
|