nvdialog_rs/
notification.rs

1/*
2 *  The MIT License (MIT)
3 *
4 *  Copyright (c) 2022-2025 Aggelos Tselios
5 *
6 *  Permission is hereby granted, free of charge, to any person obtaining a copy
7 *  of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 *  furnished to do so, subject to the following conditions:
12 *
13 *  The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25use crate::{cstr, Object};
26use nvdialog_sys::ffi::*;
27
28/// A notification dialog, which can be used to send a notification to the user
29/// through the system's API.
30///
31/// # Examples
32/// ```
33/// use nvdialog_rs::Notification;
34///
35/// let mut notification = Notification::new("Hello world!", "This is a notification.");
36/// notification.send();
37/// ```
38pub struct Notification {
39    raw: *mut NvdNotification,
40}
41
42#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
43/// [`NotificationKind`] defines a type that can represent different kinds of notifications.
44/// The enum has three variants:
45/// `Simple`, `Warning`, and `Error`, each representing a different kind of notification.
46pub enum NotificationKind {
47    Simple,
48    Warning,
49    Error,
50}
51
52impl Into<u32> for NotificationKind {
53    fn into(self) -> u32 {
54        if self == NotificationKind::Simple {
55            NotificationKind::Simple as u32
56        } else if self == NotificationKind::Warning {
57            NotificationKind::Warning as u32
58        } else if self == NotificationKind::Error {
59            NotificationKind::Error as u32
60        } else {
61            NotificationKind::Simple as u32
62        }
63    }
64}
65
66impl Notification {
67    /// Constructs a new `Notification` object with the given title, message and kind of notification.
68    ///
69    /// # Arguments
70    ///
71    /// * `title`: A string for the title / summary of the notification.
72    /// * `msg`: The actual body of the notification.
73    /// * `kind`: The kind of the notification, see [`NotificationKind`].
74    ///
75    /// # Errors
76    /// Returns an `Error` of type `OutOfMemory` if NvDialog's allocation failed.
77    ///
78    /// # Examples
79    /// ```
80    /// use nvdialog_rs::{Notification, NotificationKind};
81    /// let notification = Notification::new("Hello", "This is a notification", NotificationKind::Simple);
82    /// ```
83    /// ## FFI
84    /// Correspons to `nvd_notification_new`.
85    pub fn new<S: AsRef<str>>(
86        title: S,
87        msg: S,
88        kind: NotificationKind,
89    ) -> Result<Self, crate::Error> {
90        let t = cstr!(title.as_ref());
91        let m = cstr!(msg.as_ref());
92        let raw = unsafe { nvd_notification_new(t.as_ptr(), m.as_ptr(), kind.into()) };
93
94        if raw.is_null() {
95            return Err(crate::Error::OutOfMemory);
96        }
97        Ok(Self { raw })
98    }
99
100    /// The `add_action` function in Rust adds a notification action with a specified name, value, and
101    /// pointer.
102    ///
103    /// Arguments:
104    ///
105    /// * [`name`]: A string that that represents the name of an action to be added.
106    /// * [`val`]: The value to save in the address pointed to by [`ptr`]
107    /// * [`ptr`]: A pointer to the variable to save the response to
108    pub fn add_action<S: AsRef<str>>(&mut self, name: S, val: i32, ptr: &mut i32) {
109        let a = cstr!(name.as_ref());
110        unsafe {
111            nvd_add_notification_action(self.raw, a.as_ptr(), val, ptr);
112        }
113    }
114
115    /// Sends the notification to the desktop notification system. If the notification has
116    /// already been shown or sent, calling this method again will have no effect.
117    ///
118    /// # Examples
119    ///
120    /// ```
121    /// use nvdialog_rs::{Notification, NotificationKind};
122    ///
123    /// let mut notification = Notification::new("Title", "Body", NotificationKind::Simple)
124    ///     .expect("Failed to create notification");
125    ///
126    /// // Send the notification
127    /// notification.send();
128    /// ```
129    ///
130    /// # FFI
131    /// Corresponds to `nvd_send_notification`.
132    pub fn send(&self) {
133        unsafe { nvd_send_notification(self.raw) }
134    }
135}
136
137impl Object for Notification {
138    type NativeType = NvdNotification;
139    type ReturnValue = ();
140
141    fn get_raw(&self) -> *mut Self::NativeType {
142        self.raw
143    }
144
145    fn show(&self) {
146        self.send();
147    }
148
149    fn free(&mut self) {
150        unsafe { nvd_delete_notification(self.raw) };
151    }
152}
153
154impl Drop for Notification {
155    fn drop(&mut self) {
156        self.free();
157    }
158}