mm_client_common/
logging.rs1use std::sync::{Arc, OnceLock};
6
7#[derive(uniffi::Enum)]
8pub enum LogLevel {
9 None,
10 Trace,
11 Debug,
12 Info,
13 Warn,
14 Error,
15}
16
17impl From<log::Level> for LogLevel {
18 fn from(value: log::Level) -> Self {
19 match value {
20 log::Level::Trace => LogLevel::Trace,
21 log::Level::Debug => LogLevel::Debug,
22 log::Level::Info => LogLevel::Info,
23 log::Level::Warn => LogLevel::Warn,
24 log::Level::Error => LogLevel::Error,
25 }
26 }
27}
28
29#[uniffi::export(with_foreign)]
31pub trait LogDelegate: Send + Sync + std::fmt::Debug {
32 fn log(&self, level: LogLevel, target: String, msg: String);
33}
34
35struct LogWrapper(Arc<dyn LogDelegate>);
36
37impl log::Log for LogWrapper {
38 fn enabled(&self, metadata: &log::Metadata) -> bool {
39 metadata.level() <= log::max_level()
40 }
41
42 fn log(&self, record: &log::Record) {
43 if self.enabled(record.metadata()) {
44 LogDelegate::log(
45 &*self.0,
46 record.level().into(),
47 record.target().to_owned(),
48 record.args().to_string(),
49 )
50 }
51 }
52
53 fn flush(&self) {}
54}
55
56#[uniffi::export]
58fn set_log_level(level: LogLevel) {
59 let filter = match level {
60 LogLevel::None => log::LevelFilter::Off,
61 LogLevel::Trace => log::LevelFilter::Trace,
62 LogLevel::Debug => log::LevelFilter::Debug,
63 LogLevel::Info => log::LevelFilter::Info,
64 LogLevel::Warn => log::LevelFilter::Warn,
65 LogLevel::Error => log::LevelFilter::Error,
66 };
67
68 log::set_max_level(filter);
69}
70
71#[uniffi::export]
73fn set_logger(logger: Arc<dyn LogDelegate>) {
74 static LOGGER: OnceLock<LogWrapper> = OnceLock::new();
77
78 let logger = LOGGER.get_or_init(|| LogWrapper(logger));
79 log::set_logger(logger).expect("failed to set logger")
80}