libnotify_rs/wrappers/builder.rs
1use crate::{
2 api::{
3 errors::LibnotifyError,
4 notification::{HintValue, Notification, Timeout, Urgency},
5 },
6 wrappers::context::LibnotifyContext,
7};
8
9/// Higher level abstraction of `Notification`. Allow for builder pattern notification construction.
10/// Requires `LibnotifyContext`
11pub struct NotificationBuilder<'a> {
12 notification: Notification,
13 _context: &'a LibnotifyContext,
14}
15
16impl<'a> NotificationBuilder<'a> {
17 /// Create new NotificationBuilder, with given context.
18 ///
19 /// # Errors
20 ///
21 /// This function can return LibnotifyError::{NewNotificationError, NulError}
22 ///
23 /// # Example
24 /// ```
25 /// use libnotify_rs::{builder::NotificationBuilder, context::LibnotifyContext};
26 ///
27 /// // Builder is recommended way to interact with libnotify notifications
28 ///
29 /// fn main() -> Result<(), Box<dyn std::error::Error>> {
30 /// let ctx = LibnotifyContext::new("Coffee addicted reminder")?; // builder requires context
31 ///
32 /// let notification_builder = NotificationBuilder::new(
33 /// "Remember about your coffee!",
34 /// "Only idiots forget about coffee!",
35 /// None,
36 /// &ctx,
37 /// )?;
38 ///
39 /// // you don't need to uninitialize libnotify, cause context already does that!
40 ///
41 /// Ok(())
42 /// }
43 ///
44 /// ```
45 pub fn new<T, Y>(
46 summary: &str,
47 body: T,
48 icon: Y,
49 context: &'a LibnotifyContext,
50 ) -> Result<Self, Box<dyn std::error::Error>>
51 where
52 T: Into<Option<&'a str>>,
53 Y: Into<Option<&'a str>>,
54 {
55 let notification = Notification::new(summary, body, icon)?;
56
57 Ok(Self {
58 notification,
59 _context: context,
60 })
61 }
62
63 /// Sets app name for this specific notification.
64 ///
65 /// # Errors
66 /// This function can return LibnotifyError::{NulError}
67 ///
68 /// # Example
69 /// ```ignore(Small example)
70 /// let notification_builder = NotificationBuilder::new(
71 /// "Remember about your coffee!",
72 /// "Only idiots forget about coffee!",
73 /// None,
74 /// &ctx,
75 /// )?
76 /// .set_app_name("Other app name");
77 /// ```
78 pub fn set_app_name<T: Into<Option<&'a str>>>(
79 mut self,
80 app_name: T,
81 ) -> Result<Self, LibnotifyError> {
82 if let Some(app_name) = app_name.into() {
83 self.notification.set_app_name(app_name)?;
84 }
85
86 Ok(self)
87 }
88
89 /// Sets app icon fot this specific notification.
90 ///
91 /// # Errors
92 /// This function can return LibnotifyError::{NulError}
93 ///
94 /// # Example
95 /// ```ignore(Small example)
96 /// let notification_builder = NotificationBuilder::new(
97 /// "Remember about your coffee!",
98 /// "Only idiots forget about coffee!",
99 /// None,
100 /// &ctx,
101 /// )?
102 /// .set_app_icon("STOCK-HOME")?;
103 /// ```
104 pub fn set_app_icon<T: Into<Option<&'a str>>>(
105 mut self,
106 app_icon: T,
107 ) -> Result<Self, LibnotifyError> {
108 if let Some(app_icon) = app_icon.into() {
109 self.notification.set_app_icon(app_icon)?;
110 }
111
112 Ok(self)
113 }
114
115 /// Sets category for this specific notification
116 ///
117 /// # Errors
118 /// This function can return LibnotifyError::{NulError}
119 pub fn set_category<T: Into<Option<&'a str>>>(
120 mut self,
121 category: T,
122 ) -> Result<Self, LibnotifyError> {
123 if let Some(category) = category.into() {
124 self.notification.set_category(category)?;
125 }
126
127 Ok(self)
128 }
129
130 /// Set hint for this specific notification
131 /// # Errors
132 /// This function can return LibnotifyError::{NulError, AllocationError}
133 pub fn set_hint(mut self, key: &str, value: HintValue) -> Result<Self, LibnotifyError> {
134 self.notification.set_hint(key, value)?;
135 Ok(self)
136 }
137
138 /// Set timeout until close
139 ///
140 /// # Example
141 /// ```
142 /// use libnotify_rs::{builder::NotificationBuilder, context::LibnotifyContext};
143 ///
144 /// fn main() -> Result<(), Box<dyn std::error::Error>> {
145 /// let ctx = LibnotifyContext::new("Coffee addicted reminder")?; // builder requires context
146 ///
147 /// let notification_builder = NotificationBuilder::new(
148 /// "Remember about your coffee!",
149 /// "Only idiots forget about coffee!",
150 /// None,
151 /// &ctx,
152 /// )?
153 /// .set_timeout(libnotify_rs::api::notification::Timeout::Never);
154 ///
155 /// Ok(())
156 /// }
157 /// ```
158 pub fn set_timeout<T: Into<Option<Timeout>>>(mut self, timeout: T) -> Self {
159 if let Some(timeout) = timeout.into() {
160 self.notification.set_timeout(timeout);
161 }
162
163 self
164 }
165
166 /// Set notification urgency level
167 ///
168 /// # Example
169 /// ```
170 /// use libnotify_rs::{builder::NotificationBuilder, context::LibnotifyContext};
171 ///
172 /// fn main() -> Result<(), Box<dyn std::error::Error>> {
173 /// let ctx = LibnotifyContext::new("Coffee addicted reminder")?; // builder requires context
174 ///
175 /// let notification_builder = NotificationBuilder::new(
176 /// "Remember about your coffee!",
177 /// "Only idiots forget about coffee!",
178 /// None,
179 /// &ctx,
180 /// )?
181 /// .set_urgency(libnotify_rs::api::notification::Urgency::Critical);
182 ///
183 /// Ok(())
184 /// }
185 /// ```
186 pub fn set_urgency<T: Into<Option<Urgency>>>(mut self, urgency: T) -> Self {
187 if let Some(urgency) = urgency.into() {
188 self.notification.set_urgency(urgency);
189 }
190
191 self
192 }
193
194 /// Add callback
195 ///
196 /// # Errors
197 /// This function can return LibnotifyError::NulError
198 ///
199 /// # Example
200 /// ```
201 ///
202 /// use libnotify_rs::{builder::NotificationBuilder, context::LibnotifyContext};
203 ///
204 /// fn main() -> Result<(), Box<dyn std::error::Error>> {
205 /// let ctx = LibnotifyContext::new("Coffee addicted reminder")?; // builder requires context
206 ///
207 /// let notification_builder = NotificationBuilder::new(
208 /// "Remember about your coffee!",
209 /// "Only idiots forget about coffee!",
210 /// None,
211 /// &ctx,
212 /// )?
213 /// .add_action("default", "super cool action", |action| {
214 /// println!("Action: {} was run!", action);
215 /// });
216 ///
217 /// Ok(())
218 /// }
219 /// ```
220 pub fn add_action<F>(
221 mut self,
222 action: &str,
223 label: &str,
224 callback: F,
225 ) -> Result<Self, LibnotifyError>
226 where
227 F: Fn(&str) + 'static,
228 {
229 self.notification.add_action(action, label, callback)?;
230 Ok(self)
231 }
232
233 /// Show notification
234 ///
235 /// Uses `&self` borrow, so you can use this object later, after showing.
236 ///
237 /// # Errors
238 /// This function can return LibnotifyError::{GerrorError, AllocationError}
239 ///
240 /// # Example
241 /// ```no_run(No notification daemon on CI)
242 /// use libnotify_rs::{builder::NotificationBuilder, context::LibnotifyContext};
243 ///
244 /// /// Builder is recommended way to interact with libnotify notifications
245 ///
246 /// fn main() -> Result<(), Box<dyn std::error::Error>> {
247 /// let ctx = LibnotifyContext::new("Coffee addicted reminder")?; // builder requires context
248 ///
249 /// let notification_builder = NotificationBuilder::new(
250 /// "Remember about your coffee!",
251 /// "Only idiots forget about coffee!",
252 /// None,
253 /// &ctx,
254 /// )?
255 /// .set_urgency(libnotify_rs::api::notification::Urgency::Critical)
256 /// .set_timeout(libnotify_rs::api::notification::Timeout::Never)
257 /// .set_category("Coffee")?;
258 ///
259 /// notification_builder.show()?;
260 ///
261 /// Ok(())
262 /// }
263 /// ```
264 pub fn show(&self) -> Result<(), LibnotifyError> {
265 self.notification.show()?;
266 Ok(())
267 }
268
269 /// Close notification synchronously.
270 ///
271 /// Uses `&self` borrow, so you can use this object later, after closing.
272 ///
273 /// # Errors
274 /// This function can return LibnotifyError::{GerrorError, AllocationError}
275 ///
276 /// # Example
277 /// ```no_run(No notification daemon on CI)
278 /// use libnotify_rs::{builder::NotificationBuilder, context::LibnotifyContext};
279 ///
280 /// /// Builder is recommended way to interact with libnotify notifications
281 ///
282 /// fn main() -> Result<(), Box<dyn std::error::Error>> {
283 /// let ctx = LibnotifyContext::new("Coffee addicted reminder")?; // builder requires context
284 ///
285 /// let notification_builder = NotificationBuilder::new(
286 /// "Remember about your coffee!",
287 /// "Only idiots forget about coffee!",
288 /// None,
289 /// &ctx,
290 /// )?
291 /// .set_urgency(libnotify_rs::api::notification::Urgency::Critical)
292 /// .set_timeout(libnotify_rs::api::notification::Timeout::Never)
293 /// .set_category("Coffee")?;
294 ///
295 /// notification_builder.show()?;
296 /// notification_builder.close()?;
297 /// Ok(())
298 /// }
299 /// ```
300 pub fn close(&self) -> Result<(), LibnotifyError> {
301 self.notification.close()?;
302 Ok(())
303 }
304}