ferron_common/
logging.rs

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