use std::{borrow::Borrow, ffi::CString, sync::Arc};
use crate::{
rcl_bindings::{rcutils_logging_set_default_logger_level, rcutils_logging_set_logger_level},
LogParams, LogSeverity, LoggerName, RclrsError, ToLogParams, ToResult, ENTITY_LIFECYCLE_MUTEX,
};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Logger {
name: Arc<str>,
c_name: Arc<CString>,
}
impl Logger {
pub fn new(name: impl Borrow<str>) -> Result<Logger, RclrsError> {
let name: Arc<str> = name.borrow().into();
let c_name = match CString::new((*name).to_owned()) {
Ok(c_name) => c_name,
Err(err) => {
return Err(RclrsError::StringContainsNul {
s: (*name).to_owned(),
err,
});
}
};
Ok(Self {
name,
c_name: Arc::new(c_name),
})
}
pub fn create_child(&self, child_name: impl Borrow<str>) -> Result<Logger, RclrsError> {
if self.name.is_empty() {
Self::new(child_name)
} else {
Self::new(format!("{}.{}", &self.name, child_name.borrow()))
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn set_level(&self, severity: LogSeverity) -> Result<(), RclrsError> {
let _lifecycle = ENTITY_LIFECYCLE_MUTEX.lock().unwrap();
unsafe {
rcutils_logging_set_logger_level(self.c_name.as_ptr(), severity.as_native() as i32).ok()
}
}
pub fn set_default_level(severity: LogSeverity) {
let _lifecycle = ENTITY_LIFECYCLE_MUTEX.lock().unwrap();
unsafe {
rcutils_logging_set_default_logger_level(severity.as_native() as i32);
}
}
}
impl<'a> ToLogParams<'a> for &'a Logger {
fn to_log_params(self) -> LogParams<'a> {
LogParams::new(LoggerName::Validated(&self.c_name))
}
}
impl Default for Logger {
fn default() -> Self {
Self::new("").unwrap()
}
}
impl std::hash::Hash for Logger {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}