use crate::{rcl_bindings::RCUTILS_LOG_SEVERITY, Clock};
use std::{borrow::Borrow, ffi::CString, time::Duration};
#[derive(Debug, Clone, Copy)]
pub struct LogParams<'a> {
logger_name: LoggerName<'a>,
severity: LogSeverity,
occurs: LogOccurrence,
throttle: Duration,
throttle_clock: ThrottleClock<'a>,
only_if: bool,
}
impl<'a> LogParams<'a> {
pub fn new(logger_name: LoggerName<'a>) -> Self {
Self {
logger_name,
severity: Default::default(),
occurs: Default::default(),
throttle: Duration::new(0, 0),
throttle_clock: Default::default(),
only_if: true,
}
}
pub fn get_logger_name(&self) -> &LoggerName<'_> {
&self.logger_name
}
pub fn get_severity(&self) -> LogSeverity {
self.severity
}
pub fn get_occurence(&self) -> LogOccurrence {
self.occurs
}
pub fn get_throttle(&self) -> Duration {
self.throttle
}
pub fn get_throttle_clock(&self) -> ThrottleClock<'a> {
self.throttle_clock
}
pub fn get_user_filter(&self) -> bool {
self.only_if
}
}
pub trait ToLogParams<'a>: Sized {
fn to_log_params(self) -> LogParams<'a>;
fn once(self) -> LogParams<'a> {
self.occurs(LogOccurrence::Once)
}
fn skip_first(self) -> LogParams<'a> {
self.occurs(LogOccurrence::SkipFirst)
}
fn occurs(self, occurs: LogOccurrence) -> LogParams<'a> {
let mut params = self.to_log_params();
params.occurs = occurs;
params
}
fn throttle(self, throttle: Duration) -> LogParams<'a> {
let mut params = self.to_log_params();
params.throttle = throttle;
params
}
fn throttle_clock(self, clock: ThrottleClock<'a>) -> LogParams<'a> {
let mut params = self.to_log_params();
params.throttle_clock = clock;
params
}
fn only_if(self, only_if: bool) -> LogParams<'a> {
let mut params = self.to_log_params();
params.only_if = only_if;
params
}
fn debug(self) -> LogParams<'a> {
self.severity(LogSeverity::Debug)
}
fn info(self) -> LogParams<'a> {
self.severity(LogSeverity::Info)
}
fn warn(self) -> LogParams<'a> {
self.severity(LogSeverity::Warn)
}
fn error(self) -> LogParams<'a> {
self.severity(LogSeverity::Error)
}
fn fatal(self) -> LogParams<'a> {
self.severity(LogSeverity::Fatal)
}
fn severity(self, severity: LogSeverity) -> LogParams<'a> {
let mut params = self.to_log_params();
params.severity = severity;
params
}
}
#[derive(Debug, Clone, Copy)]
pub enum LoggerName<'a> {
Validated(&'a CString),
Unvalidated(&'a str),
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum LogSeverity {
Unset,
Debug,
Info,
Warn,
Error,
Fatal,
}
impl LogSeverity {
pub(super) fn as_native(&self) -> RCUTILS_LOG_SEVERITY {
use crate::rcl_bindings::rcl_log_severity_t::*;
match self {
LogSeverity::Unset => RCUTILS_LOG_SEVERITY_UNSET,
LogSeverity::Debug => RCUTILS_LOG_SEVERITY_DEBUG,
LogSeverity::Info => RCUTILS_LOG_SEVERITY_INFO,
LogSeverity::Warn => RCUTILS_LOG_SEVERITY_WARN,
LogSeverity::Error => RCUTILS_LOG_SEVERITY_ERROR,
LogSeverity::Fatal => RCUTILS_LOG_SEVERITY_FATAL,
}
}
#[cfg(test)]
pub(crate) fn from_native(native: i32) -> Self {
use crate::rcl_bindings::rcl_log_severity_t::*;
match native {
_ if native == RCUTILS_LOG_SEVERITY_UNSET as i32 => LogSeverity::Unset,
_ if native == RCUTILS_LOG_SEVERITY_DEBUG as i32 => LogSeverity::Debug,
_ if native == RCUTILS_LOG_SEVERITY_INFO as i32 => LogSeverity::Info,
_ if native == RCUTILS_LOG_SEVERITY_WARN as i32 => LogSeverity::Warn,
_ if native == RCUTILS_LOG_SEVERITY_ERROR as i32 => LogSeverity::Error,
_ if native == RCUTILS_LOG_SEVERITY_FATAL as i32 => LogSeverity::Fatal,
_ => panic!("Invalid native severity received: {}", native),
}
}
}
impl Default for LogSeverity {
fn default() -> Self {
Self::Info
}
}
#[derive(Debug, Clone, Copy)]
pub enum LogOccurrence {
All,
Once,
SkipFirst,
}
#[derive(Debug, Default, Clone, Copy)]
pub enum ThrottleClock<'a> {
#[default]
SteadyTime,
SystemTime,
Clock(&'a Clock),
}
impl Default for LogOccurrence {
fn default() -> Self {
Self::All
}
}
impl<'a, T: Borrow<str>> ToLogParams<'a> for &'a T {
fn to_log_params(self) -> LogParams<'a> {
LogParams::new(LoggerName::Unvalidated(self.borrow()))
}
}
impl<'a> ToLogParams<'a> for &'a str {
fn to_log_params(self) -> LogParams<'a> {
LogParams::new(LoggerName::Unvalidated(self))
}
}
impl<'a> ToLogParams<'a> for LogParams<'a> {
fn to_log_params(self) -> LogParams<'a> {
self
}
}