use colored::Color;
use lazy_static::lazy_static;
use std::io::{Error, ErrorKind};
use std::sync::{Mutex, MutexGuard, PoisonError};
use ureq::Request;
lazy_static! {
#[doc(hidden)]
pub static ref CONFIG: Mutex<Config> = Mutex::new(new());
}
pub enum Log {
Info,
Warn,
Error,
Fatal,
#[doc(hidden)]
_None,
}
#[derive(PartialEq)]
pub enum Time {
UTC,
Local,
}
pub struct Config {
#[doc(hidden)]
pub time: Time,
#[doc(hidden)]
pub info_color: Color,
#[doc(hidden)]
pub warn_color: Color,
#[doc(hidden)]
pub error_color: Color,
#[doc(hidden)]
pub fatal_color: Color,
#[doc(hidden)]
pub info_console: bool,
#[doc(hidden)]
pub warn_console: bool,
#[doc(hidden)]
pub error_console: bool,
#[doc(hidden)]
pub fatal_console: bool,
#[doc(hidden)]
pub info_web: Vec<(Request, String)>,
#[doc(hidden)]
pub warn_web: Vec<(Request, String)>,
#[doc(hidden)]
pub error_web: Vec<(Request, String)>,
#[doc(hidden)]
pub fatal_web: Vec<(Request, String)>,
#[doc(hidden)]
pub info_file: Vec<String>,
#[doc(hidden)]
pub warn_file: Vec<String>,
#[doc(hidden)]
pub error_file: Vec<String>,
#[doc(hidden)]
pub fatal_file: Vec<String>,
working_on: Log,
}
pub fn new() -> Config {
Config {
time: Time::Local,
info_color: Color::TrueColor {
r: 0,
g: 255,
b: 255,
},
warn_color: Color::TrueColor {
r: 255,
g: 215,
b: 185,
},
error_color: Color::TrueColor {
r: 255,
g: 100,
b: 0,
},
fatal_color: Color::TrueColor {
r: 255,
g: 0,
b: 0
},
info_console: true,
warn_console: true,
error_console: true,
fatal_console: true,
info_web: Vec::new(),
warn_web: Vec::new(),
error_web: Vec::new(),
fatal_web: Vec::new(),
info_file: Vec::new(),
warn_file: Vec::new(),
error_file: Vec::new(),
fatal_file: Vec::new(),
working_on: Log::_None,
}
}
impl Config {
pub fn time(mut self, time: Time) -> Self {
self.time = time;
self
}
pub fn color(mut self, color: Color) -> Result<Self, Error> {
match self.working_on {
Log::Info => self.info_color = color,
Log::Warn => self.warn_color = color,
Log::Error => self.error_color = color,
Log::Fatal => self.fatal_color = color,
Log::_None => {
return Err(Error::new(
ErrorKind::Other,
"You need to set a log type before you can set the color",
))
}
}
Ok(self)
}
pub fn console(mut self, _bool: bool) -> Result<Self, Error> {
match self.working_on {
Log::Info => self.info_console = _bool,
Log::Warn => self.warn_console = _bool,
Log::Error => self.error_console = _bool,
Log::Fatal => self.fatal_console = _bool,
Log::_None => {
return Err(Error::new(
ErrorKind::Other,
"You need to set a log type before you can set if it goes to the terminal",
))
}
}
Ok(self)
}
pub fn web(mut self, format: &str, request: Request) -> Result<Self, Error> {
match self.working_on {
Log::Info => self.info_web.push((request, format.to_string())),
Log::Warn => self.warn_web.push((request, format.to_string())),
Log::Error => self.error_web.push((request, format.to_string())),
Log::Fatal => self.fatal_web.push((request, format.to_string())),
Log::_None => {
return Err(Error::new(
ErrorKind::Other,
"You need to set a log type before you can set where it should be sent to",
))
}
}
Ok(self)
}
pub fn file(mut self, file: &str) -> Result<Self, Error> {
match self.working_on {
Log::Info => self.info_file.push(file.to_string()),
Log::Warn => self.warn_file.push(file.to_string()),
Log::Error => self.error_file.push(file.to_string()),
Log::Fatal => self.fatal_file.push(file.to_string()),
Log::_None => {
return Err(Error::new(
ErrorKind::Other,
"You need to set a log type before you can set where it should be sent to",
))
}
}
Ok(self)
}
pub fn set_type(mut self, log: Log) -> Result<Self, Error> {
match log {
Log::_None => {
return Err(Error::new(
ErrorKind::Other,
"You can not set the current log type to none",
))
}
_ => self.working_on = log,
}
Ok(self)
}
pub fn save(self) -> Result<(), PoisonError<MutexGuard<'static, Config>>> {
let mut config = CONFIG.lock()?;
*config = self;
Ok(())
}
}