//! Errors and helpers for errors. //TODO: Comment how this works (controllably optional simple or complex `main()` error messages.) use super::*; use std::{ fmt, error, }; use std::os::unix::prelude::*; pub const DEFAULT_USE_ENV: bool = std::option_env!("NO_RT_ERROR_CTL").is_none(); pub type DispersedResult = Result>; pub const ENV_NAME: &'static str = "RUST_VERBOSE"; lazy_static!{ static ref DEFAULT_ENV_VERBOSE: DispersedVerbosity = match std::option_env!("DEFAULT_ERROR") { Some("1") | Some("V") | Some("verbose") | Some("VERBOSE") | Some("v") => DispersedVerbosity::Verbose, Some("0") | _ => DispersedVerbosity::static_default(), }; } #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)] #[repr(u8)] pub enum DispersedVerbosity { Simple = 0, Verbose = 1, } impl From for bool { #[inline] fn from(from: DispersedVerbosity) -> Self { from.is_verbose() } } impl Default for DispersedVerbosity { #[inline] fn default() -> Self { *DEFAULT_ENV_VERBOSE } } impl DispersedVerbosity { #[inline(always)] const fn static_default() -> Self { Self::Simple } #[inline(always)] pub const fn is_verbose(self) -> bool { (self as u8) != 0 } } fn get_env_value() -> DispersedVerbosity { match std::env::var_os(ENV_NAME) { Some(mut value) => { value.make_ascii_lowercase(); match value.as_bytes() { b"1" | b"v" | b"verbose" => DispersedVerbosity::Verbose, b"0" | b"s" | b"simple" => DispersedVerbosity::Simple, _ => DispersedVerbosity::default(), } }, None => Default::default(), } } #[inline] pub fn dispersed_env_verbosity() -> DispersedVerbosity { lazy_static! { static ref VALUE: DispersedVerbosity = get_env_value(); } *VALUE } /// A simpler error message when returning an `eyre::Report` from main. pub struct Dispersed(eyre::Report); impl From for Dispersed { #[inline] fn from(from: eyre::Report) -> Self { Self(from) } } impl Dispersed { #[inline] pub fn into_inner(self) -> eyre::Report { self.0 } } impl Dispersed { #[inline(always)] pub fn obey_env(self) -> Dispersed { Dispersed(self.0) } } impl Dispersed { #[inline(always)] pub fn ignore_env(self) -> Dispersed { Dispersed(self.0) } } impl Dispersed { #[inline(always)] pub fn set_env(self) -> Dispersed { Dispersed(self.0) } } impl error::Error for Dispersed { #[inline] fn source(&self) -> Option<&(dyn error::Error + 'static)> { self.0.source() } } impl error::Error for Dispersed { #[inline] fn source(&self) -> Option<&(dyn error::Error + 'static)> { self.0.source() } } impl fmt::Debug for Dispersed { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) } } impl fmt::Display for Dispersed { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Debug::fmt(&self.0, f) } } impl fmt::Debug for Dispersed { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if dispersed_env_verbosity().is_verbose() { fmt::Debug::fmt(&self.0, f) } else { fmt::Display::fmt(&self.0, f) } } } impl fmt::Display for Dispersed { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if dispersed_env_verbosity().is_verbose() { fmt::Display::fmt(&self.0, f) } else { fmt::Debug::fmt(&self.0, f) } } }