rnotifylib/message/
builder.rs

1use std::time::{SystemTime, UNIX_EPOCH};
2use crate::message::component::Component;
3use crate::message::{Level, Message, MessageDetail};
4use crate::message::author::Author;
5use crate::message::detail_builder::MessageDetailBuilder;
6
7pub struct MessageBuilder {
8    level: Level,
9    title: Option<String>,
10    detail: MessageDetail,
11    component: Option<Component>,
12    author: Author,
13    unix_timestamp_millis: Option<i64>,
14}
15
16impl MessageBuilder {
17    /// Creates a new [MessageBuilder] with the following defaults:
18    /// - Level -> [Level]'s default
19    /// - Author -> The hostname of the OS or '?' if that cannot be retrieved
20    pub fn new() -> Self {
21        let author = Author::base();
22
23        Self {
24            level: Default::default(),
25            title: None,
26            detail: Default::default(),
27            component: None,
28            author,
29            unix_timestamp_millis: None,
30        }
31    }
32
33    /// Add a message body to the message builder
34    /// If not set it will be blank.
35    pub fn body<F>(&mut self, apply: F) -> &mut Self
36        where F: FnOnce(&mut MessageDetailBuilder) {
37        let mut builder = MessageDetailBuilder::new();
38        apply(&mut builder);
39        self.detail = builder.build();
40        self
41    }
42
43    /// Set the message [Level]
44    pub fn level(&mut self, level: Level) -> &mut Self {
45        self.level = level;
46        self
47    }
48
49    /// Sets the title of the message,
50    /// If not set, will be blank.
51    pub fn title<S: ToString>(&mut self, title: S) -> &mut Self {
52        self.title = Some(title.to_string());
53        self
54    }
55
56    /// Sets the [Component] of the message
57    /// By default the component will be blank
58    pub fn component(&mut self, component: Component) -> &mut Self {
59        self.component = Some(component);
60        self
61    }
62
63    /// Adds [Author] data to the message.
64    /// By default this is just the hostname of OS running it ('?' if this cannot be retrieved)
65    /// The argument parts is appended onto this hostname data (with a '/')
66    pub fn author<S: ToString>(&mut self, parts: S) -> &mut Self {
67        self.author.extend(parts.to_string());
68        self
69    }
70
71    /// Sets the timestamp of the message.
72    /// This is set by default to the time which the [MessageBuilder] was created.
73    ///
74    /// However, if you are using [`build_clone`](Self::build_clone) you should be using this
75    /// if you don't want your messages to all have the same timestamp.
76    pub fn timestamp(&mut self, unix_timestamp_millis: i64) -> &mut Self {
77        self.unix_timestamp_millis = Some(unix_timestamp_millis);
78        self
79    }
80
81    /// Builds the message, consuming the [MessageBuilder]
82    /// If [`timestamp`](Self::timestamp) has been set, it will be used,
83    /// otherwise the current time will be retrieved and used.
84    pub fn build(self) -> Message {
85
86        Message {
87            level: self.level,
88            title: self.title,
89            message_detail: self.detail,
90            component: self.component,
91            author: self.author,
92            unix_timestamp_millis: self.unix_timestamp_millis.unwrap_or_else(Self::get_unix_time_millis),
93        }
94    }
95
96    /// Builds a new message, without consuming the [MessageBuilder]
97    /// If [`timestamp`](Self::timestamp) has been set, it will be used,
98    /// otherwise the current time will be retrieved and used.
99    pub fn build_clone(&self) -> Message {
100        Message {
101            level: self.level.clone(),
102            title: self.title.clone(),
103            message_detail: self.detail.clone(),
104            component: self.component.clone(),
105            author: self.author.clone(),
106            unix_timestamp_millis: self.unix_timestamp_millis.unwrap_or_else(Self::get_unix_time_millis)
107        }
108    }
109
110    fn get_unix_time_millis() -> i64 {
111        SystemTime::now()
112            .duration_since(UNIX_EPOCH)
113            .expect("Expected now to be after unix epoch")
114            .as_millis() as i64
115    }
116}