1use crate::log::{log as nexus_log, LogLevel};
2use log::Log;
3
4impl From<log::Level> for LogLevel {
5 #[inline]
6 fn from(level: log::Level) -> Self {
7 match level {
8 log::Level::Error => Self::Critical,
9 log::Level::Warn => Self::Warning,
10 log::Level::Info => Self::Info,
11 log::Level::Debug => Self::Debug,
12 log::Level::Trace => Self::Trace,
13 }
14 }
15}
16
17#[derive(Debug)]
18pub struct NexusLogger {
19 channel_name: &'static str,
20}
21
22impl NexusLogger {
23 pub fn set_logger(channel_name: &'static str, filter: Option<&'static str>) {
24 #[cfg(not(feature = "log_filter"))]
25 let logger = Self { channel_name };
26
27 #[cfg(feature = "log_filter")]
28 let logger = filter::NexusLoggerFiltered::new(channel_name, filter);
29
30 let _ = log::set_boxed_logger(Box::new(logger));
31 log::set_max_level(log::LevelFilter::Trace);
32 }
33}
34
35impl Log for NexusLogger {
36 fn enabled(&self, _metadata: &log::Metadata) -> bool {
37 true
38 }
39
40 fn log(&self, record: &log::Record) {
41 let message = format!("{}", record.args());
42 nexus_log(record.level().into(), self.channel_name, message)
43 }
44
45 fn flush(&self) {}
46}
47
48#[cfg(feature = "log_filter")]
49mod filter {
50 use super::NexusLogger;
51 use env_filter::{Builder, Filter};
52 use log::Log;
53
54 #[derive(Debug)]
55 pub struct NexusLoggerFiltered {
56 logger: NexusLogger,
57 filter: Filter,
58 }
59
60 impl NexusLoggerFiltered {
61 pub fn new(channel_name: &'static str, filter: Option<&'static str>) -> Self {
62 Self {
63 logger: NexusLogger { channel_name },
64 filter: filter
65 .map(|f| Builder::new().parse(f).build())
66 .unwrap_or_else(|| {
67 Builder::new().filter_level(log::LevelFilter::Trace).build()
68 }),
69 }
70 }
71 }
72
73 impl Log for NexusLoggerFiltered {
74 fn enabled(&self, metadata: &log::Metadata) -> bool {
75 self.filter.enabled(metadata)
76 }
77
78 fn log(&self, record: &log::Record) {
79 if self.filter.matches(record) {
80 self.logger.log(record);
81 }
82 }
83
84 fn flush(&self) {}
85 }
86}