1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use lazy_static::lazy_static;
use std::ffi::CStr;
use std::sync::{Arc, Mutex};
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(u32)]
pub enum LogLevel {
Disabled,
Fatal,
Error,
Warn,
Info,
Debug,
Message,
Trace,
All,
#[doc(hidden)]
__Unknown(u32),
}
impl From<ffi::otc_log_level> for LogLevel {
fn from(value: ffi::otc_log_level) -> Self {
match value {
ffi::otc_log_level_OTC_LOG_LEVEL_DISABLED => Self::Disabled,
ffi::otc_log_level_OTC_LOG_LEVEL_FATAL => Self::Fatal,
ffi::otc_log_level_OTC_LOG_LEVEL_ERROR => Self::Error,
ffi::otc_log_level_OTC_LOG_LEVEL_WARN => Self::Warn,
ffi::otc_log_level_OTC_LOG_LEVEL_INFO => Self::Info,
ffi::otc_log_level_OTC_LOG_LEVEL_DEBUG => Self::Debug,
ffi::otc_log_level_OTC_LOG_LEVEL_MSG => Self::Message,
ffi::otc_log_level_OTC_LOG_LEVEL_TRACE => Self::Trace,
ffi::otc_log_level_OTC_LOG_LEVEL_ALL => Self::All,
_ => Self::__Unknown(value),
}
}
}
impl From<LogLevel> for ffi::otc_log_level {
fn from(value: LogLevel) -> Self {
match value {
LogLevel::Disabled => ffi::otc_log_level_OTC_LOG_LEVEL_DISABLED,
LogLevel::Fatal => ffi::otc_log_level_OTC_LOG_LEVEL_FATAL,
LogLevel::Error => ffi::otc_log_level_OTC_LOG_LEVEL_ERROR,
LogLevel::Warn => ffi::otc_log_level_OTC_LOG_LEVEL_WARN,
LogLevel::Info => ffi::otc_log_level_OTC_LOG_LEVEL_INFO,
LogLevel::Debug => ffi::otc_log_level_OTC_LOG_LEVEL_DEBUG,
LogLevel::Message => ffi::otc_log_level_OTC_LOG_LEVEL_MSG,
LogLevel::Trace => ffi::otc_log_level_OTC_LOG_LEVEL_TRACE,
LogLevel::All => ffi::otc_log_level_OTC_LOG_LEVEL_ALL,
LogLevel::__Unknown(_) => ffi::otc_log_level_OTC_LOG_LEVEL_DISABLED,
}
}
}
pub fn enable_log(level: LogLevel) {
unsafe { ffi::otc_log_enable(level.into()) };
}
pub type LoggerCallback = Box<dyn Fn(&str) + Send + Sync + 'static>;
lazy_static! {
pub static ref LOGGER_CALLBACKS: Arc<Mutex<Vec<LoggerCallback>>> = Default::default();
}
unsafe extern "C" fn ffi_logger_callback(message: *const ::std::os::raw::c_char) {
let message: &CStr = CStr::from_ptr(message);
if let Ok(message) = message.to_str() {
if let Ok(callbacks) = LOGGER_CALLBACKS.try_lock() {
for ref callback in callbacks.iter() {
callback(message);
}
}
}
}
pub fn logger_callback(callback: LoggerCallback) {
LOGGER_CALLBACKS.lock().unwrap().push(callback);
unsafe { ffi::otc_log_set_logger_callback(Some(ffi_logger_callback)) }
}