cute_log/
lib.rs

1//!This crate provides simple and cute logger.
2//!
3//!## Features
4//!
5//!- `timestamp` - Enables timestamps in logs by means of `chrono`. Enabled by default
6//!- `local_timestamp` - Enables `timestamp` and attempts to use local time. Implies `timestamp`.
7//!- `std` - Enables use of `std` feature to provide `RUST_LOG` handling.
8//!
9//!## Usage
10//!
11//!```rust
12//!const LOGGER: cute_log::Logger = cute_log::Logger::new();
13//!LOGGER.set_max_level(cute_log::log::LevelFilter::Info);
14//!let _ = LOGGER.set_logger();
15//!log::info!("it works!");
16//!```
17//!
18//!## Log level control
19//!
20//!The logger is made without any builtin filters.
21//!
22//!You can either control logs through compile time features of `log` crate.
23//!Or use `set_max_level` from the `log` crate.
24//!
25//!## Supported platforms
26//!
27//!- Android - via NDK logging library, therefore it must be linked.
28//!- Wasm - via web console API.
29//!- Any other platform with `std` available.
30
31#![no_std]
32
33pub extern crate log;
34
35mod io;
36
37///Simple Logger implementation
38///
39///It provides logger without filtering with following format:
40///`<level> [<date and time>] {<file>:<line>} - <args>`
41///
42///Timestamp is only used on `std` environment aside from Android.
43pub struct Logger;
44
45impl Logger {
46    #[inline]
47    ///Creates new instance.
48    pub const fn new() -> Self {
49        Self
50    }
51
52    #[cfg(feature = "std")]
53    ///Sets `log` max level from `RUST_LOG` or if not available, use provided default level.
54    ///
55    ///Requires `std` feature
56    pub fn set_log_env_or(&self, default_level: log::LevelFilter) {
57        extern crate std;
58
59        fn parse_rust_log(log: &str, default_level: log::LevelFilter) -> log::LevelFilter {
60            if log.eq_ignore_ascii_case("off") {
61                log::LevelFilter::Off
62            } else if log.eq_ignore_ascii_case("error") {
63                log::LevelFilter::Error
64            } else if log.eq_ignore_ascii_case("warn") {
65                log::LevelFilter::Warn
66            } else if log.eq_ignore_ascii_case("info") {
67                log::LevelFilter::Info
68            } else if log.eq_ignore_ascii_case("debug") {
69                log::LevelFilter::Debug
70            } else if log.eq_ignore_ascii_case("trace") {
71                log::LevelFilter::Trace
72            } else {
73                default_level
74            }
75        }
76
77        match std::env::var("RUST_LOG") {
78            Ok(log) => self.set_max_level(parse_rust_log(&log, default_level)),
79            Err(_) => self.set_max_level(default_level),
80        }
81    }
82
83    #[inline]
84    ///Sets `log` max level, controlling which level to print at most.
85    ///
86    ///By default it is off.
87    pub fn set_max_level(&self, level: log::LevelFilter) {
88        log::set_max_level(level);
89    }
90
91    #[inline]
92    ///Initialize self as `log` global logger.
93    pub fn set_logger(&'static self) -> Result<(), log::SetLoggerError> {
94        log::set_logger(self)
95    }
96
97    #[inline]
98    ///Initialize self as `log` global logger in debug mode only.
99    pub fn set_logger_debug(&'static self) -> Result<(), log::SetLoggerError> {
100        #[cfg(debug_assertions)]
101        {
102            log::set_logger(self)
103        }
104        #[cfg(not(debug_assertions))]
105        {
106            Ok(())
107        }
108    }
109}
110
111impl log::Log for Logger {
112    #[inline(always)]
113    fn enabled(&self, _: &log::Metadata) -> bool {
114        true
115    }
116
117    #[inline(always)]
118    fn log(&self, record: &log::Record) {
119        Self::print(record);
120    }
121
122    #[inline(always)]
123    fn flush(&self) {
124    }
125}