ferron_common/logging.rs
1use async_channel::Sender;
2
3/// Represents a log message with its content and error status.
4#[derive(Clone)]
5pub struct LogMessage {
6 is_error: bool,
7 message: String,
8}
9
10impl LogMessage {
11 /// Creates a new `LogMessage` instance.
12 ///
13 /// # Parameters
14 ///
15 /// - `message`: The content of the log message.
16 /// - `is_error`: A boolean indicating whether the message is an error (`true`) or not (`false`).
17 ///
18 /// # Returns
19 ///
20 /// A `LogMessage` object containing the specified message and error status.
21 pub fn new(message: String, is_error: bool) -> Self {
22 Self { is_error, message }
23 }
24
25 /// Consumes the `LogMessage` and returns its components.
26 ///
27 /// # Returns
28 ///
29 /// A tuple containing:
30 /// - `String`: The content of the log message.
31 /// - `bool`: A boolean indicating whether the message is an error.
32 pub fn get_message(self) -> (String, bool) {
33 (self.message, self.is_error)
34 }
35}
36
37/// Facilitates logging of error messages through a provided logger sender.
38pub struct ErrorLogger {
39 loggers: Vec<Sender<LogMessage>>,
40}
41
42impl ErrorLogger {
43 /// Creates a new `ErrorLogger` instance.
44 ///
45 /// # Parameters
46 ///
47 /// - `logger`: A `Sender<LogMessage>` used for sending log messages.
48 ///
49 /// # Returns
50 ///
51 /// A new `ErrorLogger` instance associated with the provided logger.
52 pub fn new(logger: Sender<LogMessage>) -> Self {
53 Self { loggers: vec![logger] }
54 }
55
56 /// Creates a new `ErrorLogger` instance with multiple loggers.
57 ///
58 /// # Parameters
59 ///
60 /// - `loggers`: A vector of `Sender<LogMessage>` used for sending log messages.
61 ///
62 /// # Returns
63 ///
64 /// A new `ErrorLogger` instance associated with multiple provided loggers.
65 pub fn new_multiple(loggers: Vec<Sender<LogMessage>>) -> Self {
66 Self { loggers }
67 }
68
69 /// Creates a new `ErrorLogger` instance without any underlying logger.
70 ///
71 /// # Returns
72 ///
73 /// A new `ErrorLogger` instance not associated with any logger.
74 pub fn without_logger() -> Self {
75 Self { loggers: vec![] }
76 }
77
78 /// Logs an error message asynchronously.
79 ///
80 /// # Parameters
81 ///
82 /// - `message`: A string slice containing the error message to be logged.
83 ///
84 /// # Examples
85 ///
86 /// ```
87 /// # use ferron_common::logging::ErrorLogger;
88 /// # #[tokio::main]
89 /// # async fn main() {
90 /// let (tx, mut rx) = async_channel::bounded(100);
91 /// let logger = ErrorLogger::new(tx);
92 /// logger.log("An error occurred").await;
93 /// # }
94 /// ```
95 pub async fn log(&self, message: &str) {
96 for logger in &self.loggers {
97 logger
98 .send(LogMessage::new(String::from(message), true))
99 .await
100 .unwrap_or_default();
101 }
102 }
103}
104
105impl Clone for ErrorLogger {
106 /// Clone a `ErrorLogger`.
107 ///
108 /// # Returns
109 ///
110 /// A cloned `ErrorLogger` instance
111 fn clone(&self) -> Self {
112 Self {
113 loggers: self.loggers.clone(),
114 }
115 }
116}