logger.rs (2001B)
1 use std::io::Write; 2 use std::{fmt, io}; 3 4 use log::{LevelFilter, Metadata, Record, set_boxed_logger, set_max_level}; 5 6 use kanit_common::error::{Context, Result}; 7 8 const SYMBOLS: [char; 5] = ['!', '=', '*', '&', '#']; 9 10 const COLORS: [Colors; 5] = [ 11 Colors::BrightRed, 12 Colors::BrightYellow, 13 Colors::BrightGreen, 14 Colors::BrightCyan, 15 Colors::BrightMagenta, 16 ]; 17 18 #[repr(u8)] 19 #[derive(Copy, Clone)] 20 pub enum Colors { 21 Black = 0, 22 Red = 1, 23 Green = 2, 24 Yellow = 3, 25 Blue = 4, 26 Magenta = 5, 27 Cyan = 6, 28 White = 7, 29 BrightBlack = 8, 30 BrightRed = 9, 31 BrightGreen = 10, 32 BrightYellow = 11, 33 BrightBlue = 12, 34 BrightMagenta = 13, 35 BrightCyan = 14, 36 BrightWhite = 15, 37 } 38 39 impl Colors { 40 pub fn reset() -> &'static str { 41 "\x1b[0m" 42 } 43 } 44 45 impl fmt::Display for Colors { 46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 47 write!(f, "\x1b[38;5;{}m", *self as u16) 48 } 49 } 50 51 // temporary solution 52 // logger should switch to a journal once initialized 53 pub struct InitializationLogger { 54 level: LevelFilter, 55 } 56 57 impl InitializationLogger { 58 pub fn init(level: LevelFilter) -> Result<()> { 59 let logger = Self { level }; 60 61 set_max_level(level); 62 set_boxed_logger(Box::new(logger)).context("failed to initialize logger")?; 63 64 Ok(()) 65 } 66 } 67 68 impl log::Log for InitializationLogger { 69 fn enabled(&self, metadata: &Metadata) -> bool { 70 metadata.level() <= self.level 71 } 72 73 fn log(&self, record: &Record) { 74 if self.enabled(record.metadata()) { 75 let idx = (record.level() as usize) - 1; 76 let sym = SYMBOLS[idx]; 77 let color = COLORS[idx]; 78 79 let mut stdout = io::stdout().lock(); 80 81 // we can't handle error 82 let _ = writeln!( 83 &mut stdout, 84 "{color}{sym}{} {}", 85 Colors::reset(), 86 record.args() 87 ); 88 } 89 } 90 91 fn flush(&self) {} 92 }