use nng_c_sys::nng_log_set_level;
use nng_c_sys::nng_system_logger;
use nng_c_sys::nng_null_logger;
use nng_c_sys::nng_log_set_logger;
#[derive(Copy, Clone)]
#[repr(i32)]
pub enum Level {
Error = nng_c_sys::nng_log_level::NNG_LOG_ERR,
Warn = nng_c_sys::nng_log_level::NNG_LOG_WARN,
Info = nng_c_sys::nng_log_level::NNG_LOG_NOTICE,
Debug = nng_c_sys::nng_log_level::NNG_LOG_INFO,
Trace = nng_c_sys::nng_log_level::NNG_LOG_DEBUG,
}
impl Level {
pub const fn new() -> Self {
if cfg!(debug_assertions) {
Self::Debug
} else {
Self::Warn
}
}
}
impl Default for Level {
#[inline(always)]
fn default() -> Self {
Self::new()
}
}
pub fn disable_logging() {
unsafe {
nng_log_set_logger(Some(nng_null_logger));
}
}
pub fn enable_logging(level: Level) {
unsafe {
nng_log_set_level(level as _);
nng_log_set_logger(Some(nng_system_logger));
}
}
#[cfg(feature = "log")]
pub fn enable_log_logging(level: Level) {
use core::ffi::CStr;
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) {
const NNG: &str = "NNG";
if msg.is_null() {
return;
}
let level = match level {
nng_c_sys::nng_log_level::NNG_LOG_DEBUG => log::Level::Trace,
nng_c_sys::nng_log_level::NNG_LOG_INFO => log::Level::Debug,
nng_c_sys::nng_log_level::NNG_LOG_NOTICE => log::Level::Info,
nng_c_sys::nng_log_level::NNG_LOG_WARN => log::Level::Warn,
nng_c_sys::nng_log_level::NNG_LOG_ERR => log::Level::Error,
_ => return,
};
let msg = match CStr::from_ptr(msg).to_str() {
Ok(msg) => msg,
Err(_) => return,
};
let nng_tag = if msg_id.is_null() {
NNG
} else {
match CStr::from_ptr(msg_id).to_str() {
Ok(msg) => msg,
Err(_) => NNG,
}
};
log::log!(level, "{}: {}", nng_tag, msg);
}
unsafe {
nng_log_set_level(level as _);
nng_log_set_logger(Some(nng_rust_log_logger));
}
}
#[cfg(feature = "tracing")]
pub fn enable_tracing(level: Level) {
use core::ffi::CStr;
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) {
const NNG: &str = "NNG";
if msg.is_null() {
return;
}
let msg = match CStr::from_ptr(msg).to_str() {
Ok(msg) => msg,
Err(_) => return,
};
let target = if msg_id.is_null() {
NNG
} else {
match CStr::from_ptr(msg_id).to_str() {
Ok(msg) => msg,
Err(_) => NNG,
}
};
match level {
nng_c_sys::nng_log_level::NNG_LOG_DEBUG => tracing::trace!(target, "{}", msg),
nng_c_sys::nng_log_level::NNG_LOG_INFO => tracing::debug!(target, "{}", msg),
nng_c_sys::nng_log_level::NNG_LOG_NOTICE => tracing::info!(target, "{}", msg),
nng_c_sys::nng_log_level::NNG_LOG_WARN => tracing::warn!(target, "{}", msg),
nng_c_sys::nng_log_level::NNG_LOG_ERR => tracing::error!(target, "{}", msg),
_ => (),
};
}
unsafe {
nng_log_set_level(level as _);
nng_log_set_logger(Some(nng_rust_tracing_logger));
}
}