1use std::fmt::Write;
2
3pub struct Logger {
4 effective_level: u32,
5 buffer_level: u32,
6 stderr_level: u32,
7 buffer: String,
8}
9
10pub struct InfoLogger<'a> {
11 logger: &'a mut Logger,
12}
13
14pub struct WarningLogger<'a> {
15 logger: &'a mut Logger,
16}
17
18impl Clone for Logger {
19 fn clone(&self) -> Self {
20 Self {
21 effective_level: self.effective_level,
22 buffer_level: self.buffer_level,
23 stderr_level: self.stderr_level,
24 buffer: String::new(), }
26 }
27}
28
29impl Logger {
30 pub fn new(buffer_level: u32, stderr_level: u32) -> Self {
40 Self {
41 buffer_level,
42 stderr_level,
43 effective_level: std::cmp::max(buffer_level, stderr_level),
44 buffer: String::new(),
45 }
46 }
47
48 pub fn warn(&mut self, s: &str) {
49 if self.level_enabled(1) {
50 self.write_warning("Warning: ");
51 self.write_warning(s);
52 self.write_warning("\n");
53 }
54 }
55
56 pub fn info(&mut self, s: &str) {
57 if self.level_enabled(2) {
58 self.write_info(s);
59 self.write_info("\n");
60 }
61 }
62
63 pub fn write_warning(&mut self, s: &str) {
64 self.write_level(1, s);
65 }
66
67 pub fn write_info(&mut self, s: &str) {
68 self.write_level(2, s);
69 }
70
71 pub fn write_buffer(&mut self, s: &str) {
72 self.buffer.push_str(s);
73 }
74
75 #[inline(always)]
76 pub fn write_level(&mut self, level: u32, s: &str) {
77 if self.buffer_level >= level {
78 self.buffer.push_str(s);
79 }
80 if self.stderr_level >= level {
81 eprint!("{}", s);
82 }
83 }
84
85 #[inline(always)]
86 pub fn level_enabled(&self, level: u32) -> bool {
87 level <= self.effective_level
88 }
89
90 #[inline(always)]
91 pub fn effective_level(&self) -> u32 {
92 self.effective_level
93 }
94
95 #[inline(always)]
96 pub fn buffer_level(&self) -> u32 {
97 self.buffer_level
98 }
99
100 #[inline(always)]
101 pub fn stderr_level(&self) -> u32 {
102 self.stderr_level
103 }
104
105 pub fn set_buffer_level(&mut self, buffer_level: u32) {
106 self.buffer_level = buffer_level;
107 self.effective_level = std::cmp::max(self.effective_level, self.buffer_level);
108 }
109
110 pub fn set_stderr_level(&mut self, stderr_level: u32) {
111 self.stderr_level = stderr_level;
112 self.effective_level = std::cmp::max(self.effective_level, self.stderr_level);
113 }
114
115 pub fn get_buffer(&self) -> &str {
116 &self.buffer
117 }
118
119 pub fn get_and_clear_logs(&mut self) -> String {
120 std::mem::take(&mut self.buffer)
121 }
122
123 pub fn info_logger(&mut self) -> InfoLogger {
124 InfoLogger { logger: self }
125 }
126
127 pub fn warning_logger(&mut self) -> WarningLogger {
128 WarningLogger { logger: self }
129 }
130}
131
132impl Write for InfoLogger<'_> {
133 fn write_str(&mut self, s: &str) -> std::fmt::Result {
134 self.logger.write_info(s);
135 Ok(())
136 }
137}
138
139impl Write for WarningLogger<'_> {
140 fn write_str(&mut self, s: &str) -> std::fmt::Result {
141 self.logger.write_warning(s);
142 Ok(())
143 }
144}