rnotifylib/message/
mod.rs

1use std::cmp::Ordering;
2use std::fmt::Debug;
3use message::formatted_detail::FormattedMessageDetail;
4use serde::{Serialize, Deserialize};
5use crate::message;
6use crate::message::author::Author;
7use crate::message::component::Component;
8
9pub mod formatted_detail;
10pub mod author;
11pub mod component;
12pub mod builder;
13pub mod detail_builder;
14
15/// A Message represents a [`MessageDestination`] independent way to send a message to a platform.
16/// **However** - not every destination will support every type of formatting, or may have length / size
17/// restrictions - so be aware of this. Destinations should do their best to receive the message, even if they
18/// have to ignore formatting to do so.
19///
20/// To construct a Message, consider using [`MessageBuilder`] or [`MessageDetailBuilder`] to make
21/// your life easier.
22///
23/// # Parts of a Message #
24/// - [Level] - Severity of message
25/// - Title - Optional, short snappy summary of what the message is about
26/// - [MessageDetail] - Structured body text supporting formatting
27/// - [Component] - Optional, indicating what the message is about, e.g a program or server.
28/// - [Author] - Who created the message
29/// - Timestamp - The unix timestamp in milliseconds, showing when the message was sent.
30///
31/// [`MessageDestination`]: crate::destination::MessageDestination
32/// [`MessageBuilder`]: builder::MessageBuilder
33/// [`MessageDetailBuilder`]: detail_builder::MessageDetailBuilder
34#[derive(Debug, Clone, PartialEq)]
35pub struct Message {
36    level: Level,
37    title: Option<String>,
38    message_detail: MessageDetail,
39    component: Option<Component>,
40    author: Author,
41    unix_timestamp_millis: i64,
42}
43
44impl Message {
45    pub fn new(level: Level, title: Option<String>,
46               message_detail: MessageDetail, component: Option<Component>,
47               author: Author, unix_timestamp_millis: i64,
48    ) -> Self {
49        Self {
50            level,
51            title,
52            message_detail,
53            component,
54            author,
55            unix_timestamp_millis
56        }
57    }
58
59    pub fn get_level(&self) -> &Level {
60        &self.level
61    }
62
63    pub fn get_title(&self) -> &Option<String> {
64        &self.title
65    }
66
67    pub fn get_message_detail(&self) -> &MessageDetail {
68        &self.message_detail
69    }
70
71    pub fn get_unix_timestamp_millis(&self) -> i64 {
72        self.unix_timestamp_millis
73    }
74
75    pub fn get_author(&self) -> &Author {
76        &self.author
77    }
78
79    pub fn get_component(&self) -> &Option<Component> {
80        &self.component
81    }
82}
83
84#[derive(Debug, Clone, PartialEq)]
85pub enum MessageDetail {
86    Raw(String),
87    Formatted(FormattedMessageDetail),
88}
89
90impl MessageDetail {
91    pub fn raw(&self) -> &str {
92        match &self {
93            MessageDetail::Raw(raw) => raw,
94            MessageDetail::Formatted(formatted) => formatted.raw()
95        }
96    }
97
98    pub fn has_formatting(&self) -> bool {
99        matches!(&self, MessageDetail::Formatted(_))
100    }
101}
102
103impl Default for MessageDetail {
104    fn default() -> Self {
105        Self::Raw(String::new())
106    }
107}
108
109/// The level / severity of the [Message]. This can be thought of as the log level.
110/// This is used in conjunction to [Component] to indicate how a message should be
111/// routed.
112#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
113#[cfg_attr(feature = "binary", derive(clap::ArgEnum))]
114pub enum Level {
115    /// Indicates an informational message when everything is working properly.
116    /// # Examples #
117    /// - A job has completed successfully, e.g a backup
118    /// - A daily status update to confirm that everything is running correctly.
119    Info,
120    /// Used when something unexpected occurs that could be the source of an error,
121    /// but requires the user to check whether it is actually an issue.
122    ///
123    /// # Examples #
124    /// - A job took longer than normal
125    /// - A job failed that fails fairly regularly, but will presumably sort itself out soon.
126    Warn,
127    /// Indicates a failure has occurred.
128    ///
129    /// # Examples #
130    /// - A program crashed / had a non-zero exit code
131    /// - A monitoring program detected that another program has not completed its job
132    ///     - Possibly indicating the program is not running
133    ///     - Or the program is malfunctioning
134    /// - A program restarted in attempt to recover itself, but is expected to recover safely
135    Error,
136    /// Indicates a failure in the notifications own configuration / workings.
137    ///
138    /// # Examples #
139    /// - Sent by [`MessageRouter`] to [`Root`] level [`MessageDestination`]s when a message
140    /// cannot be sent to one or more destinations (e.g. network failure, invalid tokens)
141    ///
142    /// [`Root`]: crate::destination::routed_destination::MessageRoutingBehaviour::Root
143    /// [`MessageDestination`]: crate::destination::MessageDestination
144    /// [`MessageRouter`]: crate::message_router::MessageRouter
145    SelfError,
146}
147
148impl Default for Level {
149    fn default() -> Self {
150        Self::Info
151    }
152}
153
154impl Level {
155    pub(crate) fn get_priority(&self) -> u32 {
156        match &self {
157            Self::Info => 1,
158            Self::Warn => 3,
159            Self::Error => 4,
160            Self::SelfError => 5,
161        }
162    }
163
164    /// Gets the least severe [Level]
165    pub fn min() -> Level {
166        Level::Info
167    }
168
169    /// Gets the most severe [Level]
170    pub fn max() -> Level {
171        Level::SelfError
172    }
173}
174
175impl PartialOrd<Self> for Level {
176    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
177        Some(self.cmp(other))
178    }
179}
180
181impl Ord for Level {
182    fn cmp(&self, other: &Self) -> Ordering {
183        self.get_priority().cmp(&other.get_priority())
184    }
185}