1use crate::{
2 task::TaskLocalErr,
3};
4use log::SetLoggerError;
5use std::{
6 panic::Location,
7 error::Error as StdError,
8 io::{Error as IoError, ErrorKind as IoErrorKind},
9 ffi::NulError,
10 sync::PoisonError,
11 fmt,
12};
13
14pub type Result<T> = std::result::Result<T, ErrorKind>;
16
17#[derive(PartialEq, Eq, Ord, PartialOrd)]
43pub enum ErrorKind {
44 ContextLock,
46 ContextInconsistent,
48 ScopeNotInitialized,
50 KeyNotInitialized,
52 ParseEnv,
54 ParseArg,
56 EnvType,
58 UnknownLogLevel,
60 WriteFailed,
62 InvalFmtString,
64 LogCompatInitialized,
66 TaskLocal(TaskLocalErr),
68 IoError(IoErrorKind),
72}
73impl StdError for ErrorKind {}
74impl fmt::Display for ErrorKind {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 match *self {
77 Self::ContextLock => write!(f, "Failed to lock Context"),
78 Self::ContextInconsistent => write!(f, "Context is inconsistent"),
79 Self::ScopeNotInitialized => f.write_str("Scope not initialized"),
80 Self::KeyNotInitialized => write!(f, "LogKey is not initialized"),
81 Self::ParseEnv => write!(f, "Parse environment variable failed"),
82 Self::ParseArg => write!(f, "Parse argument string failed"),
83 Self::EnvType => write!(f, "Environment variable has unexpected type"),
84 Self::UnknownLogLevel => write!(f, "Loglevel is unknown"),
85 Self::WriteFailed => write!(f, "Failed to write logstring"),
86 Self::InvalFmtString => write!(f, "Logging string contained non utf8 characters"),
87 Self::LogCompatInitialized => write!(f, "Log Compat is already initialized"),
88 Self::TaskLocal(ref e) => write!(f, "Error '{}' in task local access", e),
89 Self::IoError(ref i) => write!(f, "IoError while writing: {:?}", i),
90 }
91 }
92}
93impl fmt::Debug for ErrorKind {
94 #[track_caller]
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 match *self {
97 Self::TaskLocal(ref e) => write!(f, "{}", e),
98 _ => write!(f, "{} in {}", self, Location::caller()),
99 }
100 }
101}
102impl From<TaskLocalErr> for ErrorKind {
106 fn from(tle: TaskLocalErr) -> Self {
107 Self::TaskLocal(tle)
108 }
109}
110impl From<IoError> for ErrorKind {
111 fn from(io: IoError) -> Self {
112 Self::IoError(io.kind())
113 }
114}
115impl<T: 'static> From<PoisonError<T>> for ErrorKind {
116 fn from(_: PoisonError<T>) -> Self {
117 Self::ContextLock
118 }
119}
120impl From<NulError> for ErrorKind {
121 fn from(_: NulError) -> Self {
122 Self::InvalFmtString
123 }
124}
125impl From<SetLoggerError> for ErrorKind {
126 fn from(_: SetLoggerError) -> Self {
127 Self::LogCompatInitialized
128 }
129}
130
131#[cfg(test)]
132mod test {
133 use super::ErrorKind::{self, *};
134 use crate::task::TaskLocalErr::*;
135 use std::io::{Error as IoError, ErrorKind::BrokenPipe};
136
137 #[test]
138 fn error_eq() {
139 assert_eq!(ParseEnv == ParseEnv, true);
140 assert_eq!(TaskLocal(BorrowError) == TaskLocal(BorrowError), true);
141 }
142
143 #[test]
144 fn error_ne() {
145 assert_eq!(ParseEnv == EnvType, false);
146 assert_eq!(TaskLocal(AccessError) == TaskLocal(BorrowError), false);
147 }
148
149 #[test]
150 fn from_other_error() {
151 assert_eq!(ErrorKind::from(IoError::from(BrokenPipe)), IoError(BrokenPipe));
152 }
153}