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}