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}