// Copyright 2022-2024 Gabriel Bjørnager Jensen. use std::error::Error as StdError; use std::fmt::{Display, Formatter}; use std::process::{ExitCode, Termination}; pub type Result = std::result::Result; #[derive(Debug)] pub enum Error { ConfigError { message: String }, IllegalArgument { arg: String }, IllegalFieldValue { field: &'static str, value: String, source: Box }, MissingConfig, MissingField { field: &'static str }, NetworkError { source: std::io::Error }, SerialiseError { source: bzipper::Error }, } impl Display for Error { #[inline] fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { use Error::*; match *self { ConfigError { ref message } => write!(f, "unable to load configuration: \"{message}\""), IllegalArgument { ref arg } => write!(f, "illegal argument `{arg}` provided"), IllegalFieldValue { field, ref value, ref source } => write!(f, "illegal configuration value {value:?} for field `{field}`: \"{source}\""), MissingConfig => write!(f, "no configuration provided"), MissingField { field } => write!(f, "missing configuration field `{field}`"), NetworkError { ref source } => write!(f, "network error: \"{source}\""), SerialiseError { ref source } => write!(f, "error when serialising response: \"{source}\""), } } } impl StdError for Error { #[allow(clippy::match_same_arms)] #[inline] fn source(&self) -> Option<&(dyn StdError + 'static)> { use Error::*; match *self { IllegalFieldValue { ref source, .. } => Some(source.as_ref()), NetworkError { ref source } => Some(source), SerialiseError { ref source } => Some(source), _ => None, } } } impl Termination for Error { #[inline(always)] fn report(self) -> ExitCode { use Error::*; match self { | ConfigError { .. } | IllegalArgument { .. } | IllegalFieldValue { .. } | MissingConfig | MissingField { .. } => 0x2, _ => 0x1, }.into() } }