use crate::{
task::TaskLocalErr,
};
use log::SetLoggerError;
use std::{
panic::Location,
error::Error as StdError,
io::{Error as IoError, ErrorKind as IoErrorKind},
ffi::NulError,
sync::PoisonError,
fmt,
};
pub type Result<T> = std::result::Result<T, ErrorKind>;
#[derive(PartialEq, Eq, Ord, PartialOrd)]
pub enum ErrorKind {
ContextLock,
ContextInconsistent,
ScopeNotInitialized,
KeyNotInitialized,
ParseEnv,
ParseArg,
EnvType,
UnknownLogLevel,
WriteFailed,
InvalFmtString,
LogCompatInitialized,
TaskLocal(TaskLocalErr),
IoError(IoErrorKind),
}
impl StdError for ErrorKind {}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::ContextLock => write!(f, "Failed to lock Context"),
Self::ContextInconsistent => write!(f, "Context is inconsistent"),
Self::ScopeNotInitialized => f.write_str("Scope not initialized"),
Self::KeyNotInitialized => write!(f, "LogKey is not initialized"),
Self::ParseEnv => write!(f, "Parse environment variable failed"),
Self::ParseArg => write!(f, "Parse argument string failed"),
Self::EnvType => write!(f, "Environment variable has unexpected type"),
Self::UnknownLogLevel => write!(f, "Loglevel is unknown"),
Self::WriteFailed => write!(f, "Failed to write logstring"),
Self::InvalFmtString => write!(f, "Logging string contained non utf8 characters"),
Self::LogCompatInitialized => write!(f, "Log Compat is already initialized"),
Self::TaskLocal(ref e) => write!(f, "Error '{}' in task local access", e),
Self::IoError(ref i) => write!(f, "IoError while writing: {:?}", i),
}
}
}
impl fmt::Debug for ErrorKind {
#[track_caller]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::TaskLocal(ref e) => write!(f, "{}", e),
_ => write!(f, "{} in {}", self, Location::caller()),
}
}
}
impl From<TaskLocalErr> for ErrorKind {
fn from(tle: TaskLocalErr) -> Self {
Self::TaskLocal(tle)
}
}
impl From<IoError> for ErrorKind {
fn from(io: IoError) -> Self {
Self::IoError(io.kind())
}
}
impl<T: 'static> From<PoisonError<T>> for ErrorKind {
fn from(_: PoisonError<T>) -> Self {
Self::ContextLock
}
}
impl From<NulError> for ErrorKind {
fn from(_: NulError) -> Self {
Self::InvalFmtString
}
}
impl From<SetLoggerError> for ErrorKind {
fn from(_: SetLoggerError) -> Self {
Self::LogCompatInitialized
}
}
#[cfg(test)]
mod test {
use super::ErrorKind::{self, *};
use crate::task::TaskLocalErr::*;
use std::io::{Error as IoError, ErrorKind::BrokenPipe};
#[test]
fn error_eq() {
assert_eq!(ParseEnv == ParseEnv, true);
assert_eq!(TaskLocal(BorrowError) == TaskLocal(BorrowError), true);
}
#[test]
fn error_ne() {
assert_eq!(ParseEnv == EnvType, false);
assert_eq!(TaskLocal(AccessError) == TaskLocal(BorrowError), false);
}
#[test]
fn from_other_error() {
assert_eq!(ErrorKind::from(IoError::from(BrokenPipe)), IoError(BrokenPipe));
}
}