1use crate::*;
2
3
4pub struct Logger {
6 pub(crate) name : String,
7 pub(crate) write_level: Level,
8 pub(crate) print_level: Level,
9 pub(crate) writer : Writer,
10 pub(crate) for_write : fn(&Context) -> String,
11 pub(crate) for_print : fn(&Context) -> String,
12}
13
14
15impl Logger {
16 pub fn default(name: impl Into<String>) -> Self {
18 Self::new::<DefaultFormatter>(name, Config::default())
19 }
20}
21
22
23impl Logger {
24 pub fn new<F: Formatter>(name: impl Into<String>, config: Config) -> Self {
26 Logger {
27 name : name.into(),
28 write_level: config.write_level,
29 print_level: config.print_level,
30 writer : Writer::new(config),
31 for_write : F::for_write,
32 for_print : F::for_print,
33 }
34 }
35
36 #[track_caller]
46 pub fn session(&self, name: impl Into<String>, silent: bool) -> Session {
47 Session::new(name, SessionSrc::Logger(self), silent)
48 }
49
50 #[track_caller]
55 pub fn session_then<F, T>(&self, name: impl Into<String>, silent: bool, callable: F) -> T
56 where F: FnOnce(Session) -> T
57 {
58 callable(self.session(name, silent))
59 }
60}
61
62
63impl LoggableInner for Logger {
64 fn log(&self, level: Level, message: &str) {
65 let ctx = Context::new_message(
66 Source::new(&self.name),
67 level,
68 message
69 );
70
71 if level >= self.print_level {
72 println!("{}", (self.for_print)(&ctx));
73 }
74
75 if level >= self.write_level {
76 self.writer.lock().unwrap()
77 .write((self.for_write)(&ctx));
78 }
79 }
80}
81
82
83impl Loggable for Logger {
84 fn root_name(&self) -> &str {
85 &self.name
86 }
87
88 fn name(&self) -> &str {
89 &self.name
90 }
91
92 fn path(&self) -> String {
93 self.writer.lock().unwrap().path.clone()
94 }
95
96 fn write_level(&self) -> Level {
97 self.write_level
98 }
99
100 fn print_level(&self) -> Level {
101 self.print_level
102 }
103}