use std::{fmt, io};
#[derive(Debug)]
pub enum ArgsError {
#[cfg(feature = "clap")]
Clap(clap::Error),
Msg(String)
}
#[derive(Debug, Default)]
pub struct AppErrors<ApEr> {
pub init: Option<ApEr>,
pub run: Option<ApEr>,
pub shutdown: Option<ApEr>
}
impl<ApEr> AppErrors<ApEr> {
pub const fn init_failed(&self) -> bool {
self.init.is_some()
}
pub const fn run_failed(&self) -> bool {
self.run.is_some()
}
pub const fn shutdown_failed(&self) -> bool {
self.shutdown.is_some()
}
}
#[derive(Debug)]
#[allow(clippy::module_name_repetitions)]
pub enum CbErr<ApEr> {
Lib(Error),
App(ApEr),
#[cfg(feature = "rt")]
#[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
SrvApp(AppErrors<ApEr>)
}
impl<ApEr: fmt::Debug> std::error::Error for CbErr<ApEr> {}
impl<ApEr> fmt::Display for CbErr<ApEr> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Lib(e) => e.fmt(f),
Self::App(_ae) => {
write!(f, "Application-defined error")
}
#[cfg(feature = "rt")]
Self::SrvApp(e) => {
let mut v = vec![];
if e.init.is_some() {
v.push("init");
}
if e.run.is_some() {
v.push("run");
}
if e.shutdown.is_some() {
v.push("shutdown");
}
write!(f, "Server application failed [{}]", v.join(","))
}
}
}
}
impl<ApEr> CbErr<ApEr> {
pub fn unwrap_apperr(self) -> ApEr {
let Self::App(ae) = self else {
panic!("Not CbErr::App()");
};
ae
}
}
impl<ApEr> From<Error> for CbErr<ApEr> {
fn from(err: Error) -> Self {
Self::Lib(err)
}
}
#[cfg(feature = "rocket")]
impl<ApEr> From<rocket::Error> for CbErr<ApEr> {
fn from(err: rocket::Error) -> Self {
Self::Lib(Error::Rocket(err.to_string()))
}
}
impl<ApEr> From<std::io::Error> for CbErr<ApEr> {
fn from(err: std::io::Error) -> Self {
Self::Lib(Error::IO(err.to_string()))
}
}
#[derive(Debug)]
pub enum Error {
ArgP(ArgsError),
BadFormat(String),
Internal(String),
IO(String),
LumberJack(String),
Missing(String),
#[cfg(feature = "rocket")]
#[cfg_attr(docsrs, doc(cfg(feature = "rocket")))]
Rocket(String),
SubSystem(String),
Unsupported
}
#[allow(clippy::needless_pass_by_value)]
impl Error {
pub fn bad_format(s: impl ToString) -> Self {
Self::BadFormat(s.to_string())
}
pub fn internal(s: impl ToString) -> Self {
Self::Internal(s.to_string())
}
pub fn io(s: impl ToString) -> Self {
Self::IO(s.to_string())
}
pub fn lumberjack(s: impl ToString) -> Self {
Self::LumberJack(s.to_string())
}
pub fn missing(s: impl ToString) -> Self {
Self::Missing(s.to_string())
}
}
impl std::error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::ArgP(s) => {
write!(f, "Argument parser; {s:?}")
}
Self::BadFormat(s) => write!(f, "Bad format error; {s}"),
Self::Internal(s) => write!(f, "Internal error; {s}"),
Self::IO(s) => write!(f, "I/O error; {s}"),
Self::LumberJack(s) => write!(f, "LumberJack error; {s}"),
Self::Missing(s) => write!(f, "Missing data; {s}"),
#[cfg(feature = "rocket")]
Self::Rocket(s) => write!(f, "Rocket error; {s}"),
Self::SubSystem(s) => write!(f, "Service subsystem error; {s}"),
Self::Unsupported => {
write!(f, "Operation is unsupported [on this platform]")
}
}
}
}
#[cfg(windows)]
impl From<fltevtlog::InitError> for Error {
fn from(err: fltevtlog::InitError) -> Self {
Self::LumberJack(err.to_string())
}
}
#[cfg(windows)]
impl From<fltevtlog::Error> for Error {
fn from(err: fltevtlog::Error) -> Self {
Self::LumberJack(err.to_string())
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Self::IO(err.to_string())
}
}
#[cfg(windows)]
impl From<windows_result::Error> for Error {
fn from(err: windows_result::Error) -> Self {
Self::SubSystem(err.to_string())
}
}
#[cfg(feature = "rocket")]
impl From<rocket::Error> for Error {
fn from(err: rocket::Error) -> Self {
Self::Rocket(err.to_string())
}
}
#[cfg(feature = "installer")]
impl From<sidoc::Error> for Error {
fn from(err: sidoc::Error) -> Self {
Self::Internal(err.to_string())
}
}
#[cfg(windows)]
impl From<windows_service::Error> for Error {
fn from(err: windows_service::Error) -> Self {
Self::SubSystem(err.to_string())
}
}
#[cfg(windows)]
impl<ApEr> From<windows_service::Error> for CbErr<ApEr> {
fn from(err: windows_service::Error) -> Self {
Self::Lib(Error::SubSystem(err.to_string()))
}
}