diff --git a/Cargo.toml b/Cargo.toml index 25ef259..e7adbe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ categories = ["development-tools::debugging"] exclude = [".github/**"] [dependencies] +chrono = "0.4.19" embed-doc-image = "0.1.4" termcolor = "1.1.3" diff --git a/src/lib.rs b/src/lib.rs index 54964a4..2d0d7b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,11 +50,12 @@ doc = ::embed_doc_image::embed_image!("unix_logs", "images/unix_logs.png")))] //! ### Author Notes //! //! I'm still incredibly early in my Rust journey and so I wanted to get comfortable and try to pick -//! my own brain about exposing different API's in a Rust crate. I hope to expose an intuitive and +//! my own brain about exposing different APIs in a Rust crate. I hope to expose an intuitive and //! easy to understand API design that users can instantly get started with. use std::fmt::{Display, Formatter}; use std::io::Write; + use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; /// TODO @@ -70,16 +71,114 @@ pub enum Level { impl Display for Level { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - Level::TRACE => write!(f, "[TRACE]"), - Level::DEBUG => write!(f, "[DEBUG]"), - Level::INFO => write!(f, "[INFO]"), - Level::WARN => write!(f, "[WARN]"), - Level::ERROR => write!(f, "[ERROR]"), - Level::FATAL => write!(f, "[FATAL]"), + Level::TRACE => write!(f, "TRACE"), + Level::DEBUG => write!(f, "DEBUG"), + Level::INFO => write!(f, "INFO"), + Level::WARN => write!(f, "WARN"), + Level::ERROR => write!(f, "ERROR"), + Level::FATAL => write!(f, "FATAL"), } } } +#[macro_export] +macro_rules! trace { + ($str:expr) => {{ + use std::io::Write; + use termcolor::WriteColor; + + let now = chrono::Utc::now().format("%Y-%M-%dT%H:%M:%S%z"); + let mut stream = termcolor::StandardStream::stdout(termcolor::ColorChoice::Always); + stream + .set_color(termcolor::ColorSpec::new() + .set_fg(Some(termcolor::Color::Blue)) + .set_bold(true)) + .unwrap(); + writeln!(&mut stream, "[{} {}] {}", now, Level::TRACE, $str).unwrap(); + stream.reset().unwrap(); + }}; +} + +#[macro_export] +macro_rules! debug { + ($str:expr) => {{ + use std::io::Write; + use termcolor::WriteColor; + + let now = chrono::Utc::now().format("%Y-%M-%dT%H:%M:%S%z"); + let mut stream = termcolor::StandardStream::stdout(termcolor::ColorChoice::Always); + stream + .set_color(termcolor::ColorSpec::new() + .set_fg(Some(termcolor::Color::Green)) + .set_bold(true)) + .unwrap(); + writeln!(&mut stream, "[{} {}] {}", now, Level::DEBUG, $str).unwrap(); + stream.reset().unwrap(); + }}; +} + +#[macro_export] +macro_rules! info { + ($str:expr) => { + let now = chrono::Utc::now().format("%Y-%M-%dT%H:%M:%S%z"); + println!("{}", format!("[{} {}] {}", now, Level::INFO, $str)); + }; +} + +#[macro_export] +macro_rules! warn { + ($str:expr) => {{ + use std::io::Write; + use termcolor::WriteColor; + + let now = chrono::Utc::now().format("%Y-%M-%dT%H:%M:%S%z"); + let mut stream = termcolor::StandardStream::stdout(termcolor::ColorChoice::Always); + stream + .set_color(termcolor::ColorSpec::new() + .set_fg(Some(termcolor::Color::Yellow)) + .set_bold(true)) + .unwrap(); + writeln!(&mut stream, "[{} {}] {}", now, Level::WARN, $str).unwrap(); + stream.reset().unwrap(); + }}; +} + +#[macro_export] +macro_rules! error { + ($str:expr) => {{ + use std::io::Write; + use termcolor::WriteColor; + + let now = chrono::Utc::now().format("%Y-%M-%dT%H:%M:%S%z"); + let mut stream = termcolor::StandardStream::stdout(termcolor::ColorChoice::Always); + stream + .set_color(termcolor::ColorSpec::new() + .set_fg(Some(termcolor::Color::Red)) + .set_intense(true)) + .unwrap(); + writeln!(&mut stream, "[{} {}] {}", now, Level::ERROR, $str).unwrap(); + stream.reset().unwrap(); + }}; +} + +#[macro_export] +macro_rules! fatal { + ($str:expr) => {{ + use std::io::Write; + use termcolor::WriteColor; + + let now = chrono::Utc::now().format("%Y-%M-%dT%H:%M:%S%z"); + let mut stream = termcolor::StandardStream::stdout(termcolor::ColorChoice::Always); + stream + .set_color(termcolor::ColorSpec::new() + .set_fg(Some(termcolor::Color::Red)) + .set_bold(true)) + .unwrap(); + writeln!(&mut stream, "[{} {}] {}", now, Level::FATAL, $str).unwrap(); + stream.reset().unwrap(); + }}; +} + /// TODO pub struct SimpleLogger { standard_stream: StandardStream, @@ -118,10 +217,7 @@ impl SimpleLogger { .standard_stream .set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true)) .unwrap(), - Level::INFO => self - .standard_stream - .set_color(ColorSpec::new().set_fg(None)) - .unwrap(), + Level::INFO => {} Level::WARN => self .standard_stream .set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true)) diff --git a/src/main.rs b/src/main.rs index b0c5b39..28812d2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,10 @@ -use rall::{Level, SimpleLogger}; +use rall::{debug, error, fatal, info, Level, SimpleLogger, trace, warn}; fn main() { - let mut logger = SimpleLogger::default(); - logger.log(Level::TRACE, "My Best Friend Hazel :D"); - logger.log(Level::DEBUG, "My Best Friend Hazel :D"); - logger.log(Level::INFO, "My Best Friend Hazel :D"); - logger.log(Level::WARN, "My Best Friend Hazel :D"); - logger.log(Level::ERROR, "My Best Friend Hazel :D"); - logger.log(Level::FATAL, "My Best Friend Hazel :D"); + trace!("My Best Friend Hazel :D"); + debug!("My Best Friend Hazel :D"); + info!("My Best Friend Hazel :D"); + warn!("My Best Friend Hazel :D"); + error!("My Best Friend Hazel :D"); + fatal!("My Best Friend Hazel :D"); } \ No newline at end of file