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}