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 50 51 52 53 54 55 56 57 58 59 60
use std::fmt; use crate::util; #[derive(Debug)] pub enum LogLevel { Debug, Error, Warning, } impl AsRef<str> for LogLevel { fn as_ref(&self) -> &str { match self { LogLevel::Debug => "debug", LogLevel::Error => "error", LogLevel::Warning => "warning", } } } #[derive(Debug, Default)] pub struct Log<'f, M> { pub message: M, pub file: Option<&'f str>, pub line: Option<usize>, pub col: Option<usize>, } impl<'f, M> Log<'f, M> { pub fn message(message: M) -> Self { Self { message, file: None, line: None, col: None, } } } impl<'f, M> fmt::Display for Log<'f, M> where M: ToString, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.file.is_none() && self.line.is_none() && self.col.is_none() { return write!(f, "::{}", self.message.to_string()); } let args = vec![ self.file.map(|f| util::cmd_arg("file", f)), self.line.map(|l| util::cmd_arg("line", l.to_string())), self.col.map(|c| util::cmd_arg("col", c.to_string())), ]; let args = args.into_iter().flatten().collect::<Vec<_>>().join(","); write!(f, " {}::{}", args, self.message.to_string()) } }