1use std::{
2 panic::{RefUnwindSafe, UnwindSafe},
3 sync::Arc,
4};
5
6use serde::Serialize;
7use strum_macros::{Display, EnumIter};
8
9use crate::enums::{unit_enum_deserialize, unit_enum_from_str};
10
11#[derive(
13 Default, EnumIter, Display, Eq, PartialEq, PartialOrd, Ord, Clone, Copy, Debug, Serialize,
14)]
15pub enum LogLevel {
16 Debug,
17 #[default]
18 Warn,
19 Info,
20 Error,
21}
22
23unit_enum_from_str!(LogLevel);
24unit_enum_deserialize!(LogLevel);
25
26pub trait LoggingStrategy: Send {
28 fn log(&self, message: &str, level: LogLevel);
29}
30
31#[derive(Clone)]
33pub struct Logger(
34 Arc<Box<dyn LoggingStrategy + Send + Sync + UnwindSafe + RefUnwindSafe + 'static>>,
35);
36
37impl Logger {
38 pub fn new<T: LoggingStrategy + Send + Sync + UnwindSafe + RefUnwindSafe + 'static>(
40 strategy: T,
41 ) -> Self {
42 Self(Arc::new(Box::new(strategy)))
43 }
44
45 pub fn log<M: AsRef<str>>(&self, message: M, level: LogLevel) {
47 self.0.log(message.as_ref(), level)
48 }
49
50 pub fn info<M: AsRef<str>>(&self, message: M) {
52 self.0.log(message.as_ref(), LogLevel::Info)
53 }
54
55 pub fn warn<M: AsRef<str>>(&self, message: M) {
57 self.0.log(message.as_ref(), LogLevel::Warn)
58 }
59
60 pub fn error<M: AsRef<str>>(&self, message: M) {
62 self.0.log(message.as_ref(), LogLevel::Error)
63 }
64
65 pub fn debug<M: AsRef<str>>(&self, message: M) {
67 self.0.log(message.as_ref(), LogLevel::Debug)
68 }
69}