links_core 0.2.12

Core create of the links collection
Documentation
use std::{
    fmt::{Debug, Display},
    sync::Arc,
};

use log::{debug, error, info, log_enabled, trace, warn, Level};

use crate::{asserted_short_name, prelude::*};

#[derive(Debug, Clone)]
pub struct LoggerCallback<M: Messenger> {
    level_recv: Level,
    level_sent: Level,
    phantom: std::marker::PhantomData<M>,
}
impl<M: Messenger> LoggerCallback<M> {
    pub fn with_level(level_recv: Level, level_sent: Level) -> Self {
        Self {
            level_recv,
            level_sent,
            phantom: std::marker::PhantomData,
        }
    }
    pub fn with_level_ref(level_recv: Level, level_send: Level) -> Arc<Self> {
        Arc::new(Self::with_level(level_recv, level_send))
    }
    pub fn new_ref() -> Arc<Self> {
        Arc::new(Self::default())
    }

    fn log(&self, level: Level, method: &str, con_id: &ConId, text: &str) {
        let recv_t = std::any::type_name::<M::RecvT>().split("::").last().unwrap_or("Unknown").replace('>', "");
        let send_t = std::any::type_name::<M::SendT>().split("::").last().unwrap_or("Unknown").replace('>', "");
        let text = format!("{}<RecvT:{recv_t}, SendT:{send_t}>::{method} {con_id} {text}", asserted_short_name!("LoggerCallback", Self));
        match level {
            Level::Error => error!("{}", text),
            Level::Warn => warn!("{}", text),
            Level::Info => info!("{}", text),
            Level::Debug => debug!("{}", text),
            Level::Trace => trace!("{}", text),
        }
    }
}
impl<M: Messenger> Default for LoggerCallback<M> {
    fn default() -> Self {
        Self {
            level_recv: Level::Info,
            level_sent: Level::Info,
            phantom: std::marker::PhantomData,
        }
    }
}
impl<M: Messenger> Display for LoggerCallback<M> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}<recv: {}, send: {}>", asserted_short_name!("LoggerCallback", Self), self.level_recv, self.level_sent)
    }
}
impl<M: Messenger> CallbackRecvSend<M> for LoggerCallback<M> {}
impl<M: Messenger> CallbackRecv<M> for LoggerCallback<M> {
    fn on_recv(&self, con_id: &ConId, msg: &<M as Messenger>::RecvT) {
        if log_enabled!(self.level_recv) {
            self.log(self.level_recv, "on_recv", con_id, &format!("{:?}", msg));
        }
    }
}
impl<M: Messenger> CallbackSend<M> for LoggerCallback<M> {
    fn on_sent(&self, con_id: &ConId, msg: &<M as Messenger>::SendT) {
        if log_enabled!(self.level_sent) {
            self.log(self.level_sent, "on_sent", con_id, &format!("{:?}", msg));
        }
    }
}

#[cfg(test)]
#[cfg(feature = "unittest")]
mod test {

    use crate::prelude::*;
    use crate::unittest::setup::{self, messenger::CltTestMessenger, model::*};
    use log::Level;

    #[test]
    fn test_callback() {
        setup::log::configure_level(log::LevelFilter::Trace);
        let clbk = LoggerCallback::<CltTestMessenger>::with_level(Level::Trace, Level::Trace);

        for _ in 0..2 {
            let msg = CltTestMsg::Dbg(CltTestMsgDebug::new(b"hello".as_slice()));
            clbk.on_sent(&ConId::default(), &msg);
        }
        for _ in 0..2 {
            let msg = SvcTestMsg::Dbg(SvcTestMsgDebug::new(b"hello".as_slice()));
            clbk.on_recv(&ConId::default(), &msg);
        }
    }
}