1use nng_c_sys::nng_log_set_level;
4use nng_c_sys::nng_system_logger;
5use nng_c_sys::nng_null_logger;
6use nng_c_sys::nng_log_set_logger;
7
8#[derive(Copy, Clone)]
9#[repr(i32)]
10pub enum Level {
12 Error = nng_c_sys::nng_log_level::NNG_LOG_ERR,
14 Warn = nng_c_sys::nng_log_level::NNG_LOG_WARN,
16 Info = nng_c_sys::nng_log_level::NNG_LOG_NOTICE,
18 Debug = nng_c_sys::nng_log_level::NNG_LOG_INFO,
20 Trace = nng_c_sys::nng_log_level::NNG_LOG_DEBUG,
22}
23
24impl Level {
25 pub const fn new() -> Self {
29 if cfg!(debug_assertions) {
30 Self::Debug
31 } else {
32 Self::Warn
33 }
34 }
35}
36
37impl Default for Level {
38 #[inline(always)]
39 fn default() -> Self {
40 Self::new()
41 }
42}
43
44pub fn disable_logging() {
46 unsafe {
47 nng_log_set_logger(Some(nng_null_logger));
48 }
49}
50
51pub fn enable_logging(level: Level) {
55 unsafe {
56 nng_log_set_level(level as _);
57 nng_log_set_logger(Some(nng_system_logger));
58 }
59}
60
61#[cfg(feature = "log")]
62pub fn enable_log_logging(level: Level) {
68 use core::ffi::CStr;
69
70 unsafe extern "C" fn nng_rust_log_logger(level: nng_c_sys::nng_log_level::Type, _: nng_c_sys::nng_log_facility::Type, msg_id: *const core::ffi::c_char, msg: *const core::ffi::c_char) {
71 const NNG: &str = "NNG";
72
73 if msg.is_null() {
74 return;
75 }
76
77 let level = match level {
78 nng_c_sys::nng_log_level::NNG_LOG_DEBUG => log::Level::Trace,
79 nng_c_sys::nng_log_level::NNG_LOG_INFO => log::Level::Debug,
80 nng_c_sys::nng_log_level::NNG_LOG_NOTICE => log::Level::Info,
81 nng_c_sys::nng_log_level::NNG_LOG_WARN => log::Level::Warn,
82 nng_c_sys::nng_log_level::NNG_LOG_ERR => log::Level::Error,
83 _ => return,
84 };
85
86 let msg = match CStr::from_ptr(msg).to_str() {
87 Ok(msg) => msg,
88 Err(_) => return,
89 };
90
91 let nng_tag = if msg_id.is_null() {
92 NNG
93 } else {
94 match CStr::from_ptr(msg_id).to_str() {
95 Ok(msg) => msg,
96 Err(_) => NNG,
97 }
98 };
99
100 log::log!(level, "{}: {}", nng_tag, msg);
101 }
102
103 unsafe {
104 nng_log_set_level(level as _);
105 nng_log_set_logger(Some(nng_rust_log_logger));
106 }
107}
108
109#[cfg(feature = "tracing")]
110pub fn enable_tracing(level: Level) {
116 use core::ffi::CStr;
117
118 unsafe extern "C" fn nng_rust_tracing_logger(level: nng_c_sys::nng_log_level::Type, _: nng_c_sys::nng_log_facility::Type, msg_id: *const core::ffi::c_char, msg: *const core::ffi::c_char) {
119 const NNG: &str = "NNG";
120
121 if msg.is_null() {
122 return;
123 }
124
125 let msg = match CStr::from_ptr(msg).to_str() {
126 Ok(msg) => msg,
127 Err(_) => return,
128 };
129
130 let target = if msg_id.is_null() {
131 NNG
132 } else {
133 match CStr::from_ptr(msg_id).to_str() {
134 Ok(msg) => msg,
135 Err(_) => NNG,
136 }
137 };
138
139 match level {
140 nng_c_sys::nng_log_level::NNG_LOG_DEBUG => tracing::trace!(target, "{}", msg),
141 nng_c_sys::nng_log_level::NNG_LOG_INFO => tracing::debug!(target, "{}", msg),
142 nng_c_sys::nng_log_level::NNG_LOG_NOTICE => tracing::info!(target, "{}", msg),
143 nng_c_sys::nng_log_level::NNG_LOG_WARN => tracing::warn!(target, "{}", msg),
144 nng_c_sys::nng_log_level::NNG_LOG_ERR => tracing::error!(target, "{}", msg),
145 _ => (),
146 };
147 }
148
149 unsafe {
150 nng_log_set_level(level as _);
151 nng_log_set_logger(Some(nng_rust_tracing_logger));
152 }
153}