1use crate::error::ExtendedError;
2use std::fmt;
3use std::sync::Arc;
4
5#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone)]
6pub enum LogLevel {
7 Dump,
8 Trace,
9 Debug,
10 Info,
11 Normal,
12 Error,
13 Fatal,
14}
15
16#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
17pub enum LogFormat {
18 CBOR,
19 JSON,
20 Text,
21 Scriptable,
22}
23
24pub trait Logger {
25 fn level(&self) -> LogLevel;
26 fn format(&self) -> LogFormat;
27 fn fatal(&self, msg: &str);
28 fn error(&self, msg: &str);
29 fn message(&self, msg: &str);
30 fn info(&self, msg: &str);
31 fn debug(&self, msg: &str);
32 fn trace(&self, msg: &str);
33 fn script_message(&self, tag: Option<&[u8]>, msg: &[&[u8]]);
34 fn script_error(&self, tag: Option<&[u8]>, err: &dyn ExtendedError);
35 fn serialized(&self, msg: &[u8]);
36 fn serialized_error(&self, msg: &dyn ExtendedError);
37}
38
39impl<T: Logger> Logger for Arc<T> {
40 fn level(&self) -> LogLevel {
41 self.as_ref().level()
42 }
43
44 fn format(&self) -> LogFormat {
45 self.as_ref().format()
46 }
47
48 fn fatal(&self, msg: &str) {
49 self.as_ref().fatal(msg);
50 }
51
52 fn error(&self, msg: &str) {
53 self.as_ref().error(msg);
54 }
55
56 fn message(&self, msg: &str) {
57 self.as_ref().message(msg);
58 }
59
60 fn info(&self, msg: &str) {
61 self.as_ref().info(msg);
62 }
63
64 fn debug(&self, msg: &str) {
65 self.as_ref().debug(msg);
66 }
67
68 fn trace(&self, msg: &str) {
69 self.as_ref().trace(msg);
70 }
71
72 fn script_message(&self, tag: Option<&[u8]>, msg: &[&[u8]]) {
73 self.as_ref().script_message(tag, msg);
74 }
75
76 fn script_error(&self, tag: Option<&[u8]>, err: &dyn ExtendedError) {
77 self.as_ref().script_error(tag, err);
78 }
79
80 fn serialized(&self, msg: &[u8]) {
81 self.as_ref().serialized(msg);
82 }
83
84 fn serialized_error(&self, msg: &dyn ExtendedError) {
85 self.as_ref().serialized_error(msg);
86 }
87}
88
89pub trait AsLogStr<'a> {
90 fn as_log_str(&'a self) -> LogStr<'a>;
91}
92
93impl<'a> AsLogStr<'a> for &'a [u8] {
94 fn as_log_str(&'a self) -> LogStr<'a> {
95 LogStr::Bytes(self)
96 }
97}
98
99pub trait AsHexLogStr<'a> {
100 fn as_hex_log_str(&'a self) -> HexLogStr<'a>;
101}
102
103impl<'a> AsHexLogStr<'a> for &'a [u8] {
104 fn as_hex_log_str(&'a self) -> HexLogStr<'a> {
105 HexLogStr::Bytes(self)
106 }
107}
108
109pub enum LogStr<'a> {
110 Bytes(&'a [u8]),
111}
112
113impl fmt::Display for LogStr<'_> {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
115 use std::fmt::Write;
116 match self {
117 Self::Bytes(arr) => {
118 for c in arr
119 .iter()
120 .flat_map(|c| std::ascii::escape_default(*c))
121 .map(|c| c as char)
122 {
123 f.write_char(c)?
124 }
125 }
126 }
127 Ok(())
128 }
129}
130
131impl fmt::Debug for LogStr<'_> {
132 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
133 fmt::Display::fmt(self, f)
134 }
135}
136
137pub enum HexLogStr<'a> {
138 Bytes(&'a [u8]),
139}
140
141impl fmt::Display for HexLogStr<'_> {
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
143 match self {
144 Self::Bytes(arr) => {
145 for b in *arr {
146 write!(f, "{:02x}", b)?;
147 }
148 }
149 }
150 Ok(())
151 }
152}
153
154impl fmt::Debug for HexLogStr<'_> {
155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
156 fmt::Display::fmt(self, f)
157 }
158}
159
160#[macro_export]
161macro_rules! trace {
162 ($logger:expr, $($args : tt) *) => {
163 {
164 use lawn_constants::logger::{Logger, LogLevel};
165 if $logger.level() <= LogLevel::Trace {
166 $logger.trace(&format!($($args)*));
167 }
168 }
169 }
170}
171
172#[macro_export]
173macro_rules! debug {
174 ($logger:expr, $($args : tt) *) => {
175 {
176 use lawn_constants::logger::{Logger, LogLevel};
177 if $logger.level() <= LogLevel::Debug {
178 $logger.debug(&format!($($args)*));
179 }
180 }
181 }
182}
183
184#[macro_export]
185macro_rules! error {
186 ($logger:expr, $($args : tt) *) => {
187 {
188 use lawn_constants::logger::{Logger, LogLevel};
189 if $logger.level() <= LogLevel::Error {
190 $logger.error(&format!($($args)*));
191 }
192 }
193 }
194}
195
196#[macro_export]
197macro_rules! info {
198 ($logger:expr, $($args : tt) *) => {
199 {
200 use lawn_constants::logger::{Logger, LogLevel};
201 if $logger.level() <= LogLevel::Info {
202 $logger.info(&format!($($args)*));
203 }
204 }
205 }
206}
207
208#[macro_export]
209macro_rules! message {
210 ($logger:expr, $($args : tt) *) => {
211 {
212 use lawn_constants::logger::{Logger, LogLevel};
213 if $logger.level() <= LogLevel::Normal {
214 $logger.message(&format!($($args)*));
215 }
216 }
217 }
218}