use std::{
panic::{RefUnwindSafe, UnwindSafe},
sync::Arc,
};
use serde::Serialize;
use strum_macros::{Display, EnumIter};
use crate::enums::{unit_enum_deserialize, unit_enum_from_str};
#[derive(
Default, EnumIter, Display, Eq, PartialEq, PartialOrd, Ord, Clone, Copy, Debug, Serialize,
)]
pub enum LogLevel {
Debug,
#[default]
Warn,
Info,
Error,
}
unit_enum_from_str!(LogLevel);
unit_enum_deserialize!(LogLevel);
pub trait LoggingStrategy: Send {
fn log(&self, message: &str, level: LogLevel);
}
#[derive(Clone)]
pub struct Logger<'a>(
Arc<Box<dyn LoggingStrategy + Send + Sync + UnwindSafe + RefUnwindSafe + 'a>>,
);
impl<'a> Logger<'a> {
pub fn new<T: LoggingStrategy + Send + Sync + UnwindSafe + RefUnwindSafe + 'a>(
strategy: T,
) -> Self {
Self(Arc::new(Box::new(strategy)))
}
pub fn log<M: AsRef<str>>(&self, message: M, level: LogLevel) {
self.0.log(message.as_ref(), level)
}
pub fn info<M: AsRef<str>>(&self, message: M) {
self.0.log(message.as_ref(), LogLevel::Info)
}
pub fn warn<M: AsRef<str>>(&self, message: M) {
self.0.log(message.as_ref(), LogLevel::Warn)
}
pub fn error<M: AsRef<str>>(&self, message: M) {
self.0.log(message.as_ref(), LogLevel::Error)
}
pub fn debug<M: AsRef<str>>(&self, message: M) {
self.0.log(message.as_ref(), LogLevel::Debug)
}
}