1mod android;
8mod null;
9mod stderr;
10
11#[repr(i32)]
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum LogLevel {
15 Verbose = 2,
16 Debug = 3,
17 Info = 4,
18 Warn = 5,
19 Error = 6,
20 Fatal = 7,
21}
22
23pub type LogPriority = LogLevel;
25
26#[repr(u8)]
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum LogBackend {
30 Android = 0,
32 Stderr = 1,
34 Null = 2,
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47pub struct Logger {
48 backend: LogBackend,
49}
50
51impl Default for Logger {
52 fn default() -> Self {
53 #[cfg(target_os = "android")]
54 {
55 Self::new(LogBackend::Android)
56 }
57 #[cfg(not(target_os = "android"))]
58 {
59 Self::new(LogBackend::Stderr)
60 }
61 }
62}
63
64pub(super) fn sanitize(s: &str) -> String {
73 let mut out = String::with_capacity(s.len());
74 for ch in s.chars() {
75 let keep = match ch {
76 '\n' | '\t' => true,
77 '\u{20}'..='\u{7e}' => true,
78 '\u{80}'..='\u{9f}' => false, '\u{a0}'..='\u{10ffff}' => true, _ => false, };
82 if keep {
83 out.push(ch);
84 }
85 }
86 out
87}
88
89impl Logger {
90 pub fn new(backend: LogBackend) -> Self {
92 Self { backend }
93 }
94
95 pub fn log(&self, level: LogLevel, tag: &str, msg: &str) {
102 #[cfg(not(debug_assertions))]
103 if (level as i32) < (LogLevel::Error as i32) {
104 return;
105 }
106 let msg = sanitize(msg);
107 match self.backend {
108 LogBackend::Android => android::log(level, tag, &msg),
109 LogBackend::Stderr => stderr::log(level, tag, &msg),
110 LogBackend::Null => null::log(level, tag, &msg),
111 }
112 }
113}
114
115pub fn log(level: LogLevel, tag: &str, msg: &str) {
120 #[cfg(not(debug_assertions))]
121 if (level as i32) < (LogLevel::Error as i32) {
122 return;
123 }
124 let msg = sanitize(msg);
125 #[cfg(target_os = "android")]
126 {
127 android::log(level, tag, &msg);
128 }
129 #[cfg(not(target_os = "android"))]
130 {
131 stderr::log(level, tag, &msg);
132 }
133}
134
135pub fn log_write(level: LogLevel, tag: &str, msg: &str) {
137 log(level, tag, msg);
138}
139
140#[macro_export]
141macro_rules! alog_verbose {
142 ($tag:expr, $($arg:tt)*) => {
143 $crate::log::log($crate::log::LogLevel::Verbose, $tag, &format!($($arg)*))
144 };
145 ($tag:expr) => {
146 $crate::log::log($crate::log::LogLevel::Verbose, $tag, "")
147 };
148}
149
150#[macro_export]
151macro_rules! alog_debug {
152 ($tag:expr, $($arg:tt)*) => {
153 $crate::log::log($crate::log::LogLevel::Debug, $tag, &format!($($arg)*))
154 };
155 ($tag:expr) => {
156 $crate::log::log($crate::log::LogLevel::Debug, $tag, "")
157 };
158}
159
160#[macro_export]
161macro_rules! alog_info {
162 ($tag:expr, $($arg:tt)*) => {
163 $crate::log::log($crate::log::LogLevel::Info, $tag, &format!($($arg)*))
164 };
165 ($tag:expr) => {
166 $crate::log::log($crate::log::LogLevel::Info, $tag, "")
167 };
168}
169
170#[macro_export]
171macro_rules! alog_warn {
172 ($tag:expr, $($arg:tt)*) => {
173 $crate::log::log($crate::log::LogLevel::Warn, $tag, &format!($($arg)*))
174 };
175 ($tag:expr) => {
176 $crate::log::log($crate::log::LogLevel::Warn, $tag, "")
177 };
178}
179
180#[macro_export]
181macro_rules! alog_error {
182 ($tag:expr, $($arg:tt)*) => {
183 $crate::log::log($crate::log::LogLevel::Error, $tag, &format!($($arg)*))
184 };
185 ($tag:expr) => {
186 $crate::log::log($crate::log::LogLevel::Error, $tag, "")
187 };
188}
189
190#[macro_export]
191macro_rules! alog_fatal {
192 ($tag:expr, $($arg:tt)*) => {
193 $crate::log::log($crate::log::LogLevel::Fatal, $tag, &format!($($arg)*))
194 };
195 ($tag:expr) => {
196 $crate::log::log($crate::log::LogLevel::Fatal, $tag, "")
197 };
198}
199
200#[macro_export]
201macro_rules! log_verbose {
202 ($tag:expr, $($arg:tt)*) => {
203 $crate::log::log($crate::log::LogLevel::Verbose, $tag, &format!($($arg)*))
204 };
205 ($tag:expr) => {
206 $crate::log::log($crate::log::LogLevel::Verbose, $tag, "")
207 };
208}
209
210#[macro_export]
211macro_rules! log_debug {
212 ($tag:expr, $($arg:tt)*) => {
213 $crate::log::log($crate::log::LogLevel::Debug, $tag, &format!($($arg)*))
214 };
215 ($tag:expr) => {
216 $crate::log::log($crate::log::LogLevel::Debug, $tag, "")
217 };
218}
219
220#[macro_export]
221macro_rules! log_info {
222 ($tag:expr, $($arg:tt)*) => {
223 $crate::log::log($crate::log::LogLevel::Info, $tag, &format!($($arg)*))
224 };
225 ($tag:expr) => {
226 $crate::log::log($crate::log::LogLevel::Info, $tag, "")
227 };
228}
229
230#[macro_export]
231macro_rules! log_warn {
232 ($tag:expr, $($arg:tt)*) => {
233 $crate::log::log($crate::log::LogLevel::Warn, $tag, &format!($($arg)*))
234 };
235 ($tag:expr) => {
236 $crate::log::log($crate::log::LogLevel::Warn, $tag, "")
237 };
238}
239
240#[macro_export]
241macro_rules! log_error {
242 ($tag:expr, $($arg:tt)*) => {
243 $crate::log::log($crate::log::LogLevel::Error, $tag, &format!($($arg)*))
244 };
245 ($tag:expr) => {
246 $crate::log::log($crate::log::LogLevel::Error, $tag, "")
247 };
248}
249
250#[macro_export]
251macro_rules! log_fatal {
252 ($tag:expr, $($arg:tt)*) => {
253 $crate::log::log($crate::log::LogLevel::Fatal, $tag, &format!($($arg)*))
254 };
255 ($tag:expr) => {
256 $crate::log::log($crate::log::LogLevel::Fatal, $tag, "")
257 };
258}