1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#![no_std]

extern crate io;
extern crate log;
extern crate unix;

use core::fmt::Write as FmtWrite;
use core::mem::ManuallyDrop as M;
use core::sync::atomic::{ATOMIC_BOOL_INIT, AtomicBool, Ordering as Memord};
use io::Write;
use log::*;
use unix::file::*;

#[derive(Debug)]
pub struct Logger { level: LevelFilter, color: AtomicBool }

pub static logger: Logger = Logger { level: LevelFilter::Trace, color: ATOMIC_BOOL_INIT };

impl Logger {
    #[inline]
    pub fn use_color(&self, b: bool) { self.color.store(b, Memord::Relaxed); }

    #[inline]
    fn color_strs(&self, lvl: Level) -> (&'static str, &'static str) {
        if self.color.load(Memord::Relaxed) { (match lvl {
            Level::Error => "\x1B[91;1m",
            Level::Warn  => "\x1B[93m",
            Level::Info  => "\x1B[97m",
            Level::Debug => "\x1B[32m",
            _       => "",
        }, "\x1B[m") } else { ("", "") }
    }
}

impl Log for Logger {
    #[inline]
    fn enabled(&self, md: &Metadata) -> bool { self.level >= md.level() }

    #[inline]
    fn log(&self, r: &Record) {
        let mut f = M::new(File::new_unchecked(2));
        if !self.enabled(r.metadata()) { return; }
        let (a, b) = self.color_strs(r.metadata().level());
        let _ = writeln!(&mut f, "{}[{: >5}]{} @{}: {}", a, r.level(), b, r.target(), r.args());
    }

    #[inline]
    fn flush(&self) { let _ = M::new(File::new_unchecked(2)).flush(); }
}