Skip to main content

ferroui_splat/logging/
wrapping_loggers.rs

1//! `WrappingFullLogger`, `WrappingLogLevelLogger` and `WrappingPrefixLogger`.
2
3use super::{
4    short_type_name, IAllocationFreeErrorLogger, IAllocationFreeLogger, IFullLogger, ILogger,
5    LogLevel,
6};
7use std::error::Error;
8use std::rc::Rc;
9
10/// An [`IFullLogger`] over an [`ILogger`] (`WrappingFullLogger`): each method of the full logger
11/// writes to the logger it wraps.
12pub struct WrappingFullLogger {
13    inner: Rc<dyn ILogger>,
14}
15
16impl WrappingFullLogger {
17    /// A full logger over `inner`.
18    pub fn new(inner: Rc<dyn ILogger>) -> Self {
19        Self { inner }
20    }
21}
22
23impl ILogger for WrappingFullLogger {
24    fn level(&self) -> LogLevel {
25        self.inner.level()
26    }
27
28    fn write(&self, message: &str, log_level: LogLevel) {
29        self.inner.write(message, log_level);
30    }
31
32    fn write_exception(&self, exception: &dyn Error, message: &str, log_level: LogLevel) {
33        self.inner.write_exception(exception, message, log_level);
34    }
35
36    fn write_with_type(&self, message: &str, type_name: &'static str, log_level: LogLevel) {
37        self.inner.write_with_type(message, type_name, log_level);
38    }
39
40    fn write_exception_with_type(
41        &self,
42        exception: &dyn Error,
43        message: &str,
44        type_name: &'static str,
45        log_level: LogLevel,
46    ) {
47        self.inner.write_exception_with_type(exception, message, type_name, log_level);
48    }
49}
50
51impl IAllocationFreeErrorLogger for WrappingFullLogger {}
52
53impl IAllocationFreeLogger for WrappingFullLogger {}
54
55impl IFullLogger for WrappingFullLogger {}
56
57/// A logger that writes each message with its level in front, `Level: message`
58/// (`WrappingLogLevelLogger`).
59pub struct WrappingLogLevelLogger {
60    inner: Rc<dyn ILogger>,
61}
62
63impl WrappingLogLevelLogger {
64    /// A logger over `inner`.
65    pub fn new(inner: Rc<dyn ILogger>) -> Self {
66        Self { inner }
67    }
68}
69
70impl ILogger for WrappingLogLevelLogger {
71    fn level(&self) -> LogLevel {
72        self.inner.level()
73    }
74
75    fn write(&self, message: &str, log_level: LogLevel) {
76        self.inner.write(&format!("{log_level}: {message}"), log_level);
77    }
78
79    fn write_exception(&self, exception: &dyn Error, message: &str, log_level: LogLevel) {
80        self.inner.write_exception(exception, &format!("{log_level}: {message}"), log_level);
81    }
82
83    fn write_with_type(&self, message: &str, type_name: &'static str, log_level: LogLevel) {
84        self.inner.write_with_type(&format!("{log_level}: {message}"), type_name, log_level);
85    }
86
87    fn write_exception_with_type(
88        &self,
89        exception: &dyn Error,
90        message: &str,
91        type_name: &'static str,
92        log_level: LogLevel,
93    ) {
94        self.inner
95            .write_exception_with_type(exception, &format!("{log_level}: {message}"), type_name, log_level);
96    }
97}
98
99/// A logger that writes each message with the name of a type in front, `Type: message`
100/// (`WrappingPrefixLogger`): the calling type of the logger, or the type a message is written
101/// with.
102pub struct WrappingPrefixLogger {
103    inner: Rc<dyn ILogger>,
104    prefix: String,
105}
106
107impl WrappingPrefixLogger {
108    /// A logger over `inner` for the type `calling_type` (`WrappingPrefixLogger(ILogger, Type)`).
109    pub fn new(inner: Rc<dyn ILogger>, calling_type: &'static str) -> Self {
110        Self { inner, prefix: format!("{}: ", short_type_name(calling_type)) }
111    }
112}
113
114impl ILogger for WrappingPrefixLogger {
115    fn level(&self) -> LogLevel {
116        self.inner.level()
117    }
118
119    fn write(&self, message: &str, log_level: LogLevel) {
120        self.inner.write(&format!("{}{message}", self.prefix), log_level);
121    }
122
123    fn write_exception(&self, exception: &dyn Error, message: &str, log_level: LogLevel) {
124        self.inner.write_exception(exception, &format!("{}{message}", self.prefix), log_level);
125    }
126
127    fn write_with_type(&self, message: &str, type_name: &'static str, log_level: LogLevel) {
128        self.inner
129            .write_with_type(&format!("{}: {message}", short_type_name(type_name)), type_name, log_level);
130    }
131
132    fn write_exception_with_type(
133        &self,
134        exception: &dyn Error,
135        message: &str,
136        type_name: &'static str,
137        log_level: LogLevel,
138    ) {
139        self.inner.write_exception_with_type(
140            exception,
141            &format!("{}: {message}", short_type_name(type_name)),
142            type_name,
143            log_level,
144        );
145    }
146}