Skip to main content

notify_rust/
lib.rs

1//! Desktop Notifications for Rust.
2//!
3//! Desktop notifications are popup messages generated to notify the user of certain events.
4//!
5//! ## Platform Support
6//!
7//! This library was originally conceived with the [XDG](https://en.wikipedia.org/wiki/XDG) notification specification in mind.
8//! Since version 3.3 this crate also builds on macOS, however the semantics of the [XDG](https://en.wikipedia.org/wiki/XDG) specification and macOS `NSNotifications`
9//! are quite different.
10//! macOS support has grown significantly; most notification methods work on both backends.
11//! Some methods are no-ops or backend-specific; see the [platform differences](#platform-differences) table.
12//!
13//! # Examples
14//!
15//! ## Example 1: Simple Notification
16//!
17//! ```no_run
18//! # use notify_rust::*;
19//! Notification::new()
20//!     .summary("Firefox News")
21//!     .body("This will almost look like a real firefox notification.")
22//!     .icon("firefox")
23//!     .timeout(Timeout::Milliseconds(6000)) //milliseconds
24//!     .show().unwrap();
25//! ```
26//!
27//! ## Example 2: Persistent Notification
28//!
29//! ```no_run
30//! # use notify_rust::*;
31//! Notification::new()
32//!     .summary("Category:email")
33//!     .body("This has nothing to do with emails.\nIt should not go away until you acknowledge it.")
34//!     .icon("thunderbird")
35//!     .appname("thunderbird")
36//!     .hint(Hint::Category("email".to_owned()))
37//!     .hint(Hint::Resident(true)) // this is not supported by all implementations
38//!     .timeout(Timeout::Never) // this however is
39//!     .show().unwrap();
40//! ```
41//!
42//! Careful! There are no checks whether you use hints twice.
43//! It is possible to set `urgency=Low` AND `urgency=Critical`, in which case the behavior of the server is undefined.
44//!
45//! ## Example 3: Ask the user to do something
46//!
47//! ```no_run
48//! # use notify_rust::*;
49//! # #[cfg(all(unix, not(target_os = "macos")))]
50//! Notification::new().summary("click me")
51//!                    .action("default", "default")
52//!                    .action("clicked", "click here")
53//!                    .hint(Hint::Resident(true))
54//!                    .show()
55//!                    .unwrap()
56//!                    .wait_for_action(|action| match action {
57//!                                         "default" => println!("you clicked \"default\""),
58//!                                         "clicked" => println!("that was correct"),
59//!                                         // here "__closed" is a hard coded keyword
60//!                                         "__closed" => println!("the notification was closed"),
61//!                                         _ => ()
62//!                                     });
63//! ```
64//!
65//! ## Minimal Example
66//!
67//! You can omit almost everything
68//!
69//! ```no_run
70//! # use notify_rust::Notification;
71//! Notification::new().show();
72//! ```
73//!
74//! more [examples](https://github.com/hoodie/notify-rust/tree/main/examples) in the repository.
75//!
76//! # Platform Differences
77//! <details>
78//! ✔︎ = works <br/>
79//! - = will not compile
80//!
81//! ## `Notification`
82//! | method                       | XDG      | macOS (`NSUserNotifictation`) | macOS (`UNUserNotificationCenter`) | windows |
83//! |------------------------------|----------|-----------------------------  |------------------------------------|---------|
84//! | `fn appname(...)`            | ✔︎        | silent no-op                  | silent no-op                       |         |
85//! | `fn summary(...)`            | ✔︎        | ✔︎                             | ✔︎                                  | ✔︎       |
86//! | `fn subtitle(...)`           |          | ✔︎                             | ✔︎                                  | ✔︎       |
87//! | `fn body(...)`               | ✔︎        | ✔︎                             | ✔︎                                  | ✔︎       |
88//! | `fn icon(...)`               | ✔︎        | silent no-op                  | silent no-op                       |         |
89//! | `fn image_path(...)`         | ✔︎        | ✔︎                             | ✔︎                                  | ✔︎       |
90//! | `fn hint(...)`               | ✔︎        | -                             | -                                  | -       |
91//! | `fn timeout(...)`            | ✔︎        | ignored                       | ✔︎                                  | ✔︎       |
92//! | `fn urgency(...)`            | ✔︎        | -                             | ✔︎ (→ `InterruptionLevel`)          | ✔︎       |
93//! | `fn interruption_level(...)` |          |                               | ✔︎                                  |         |
94//! | `fn action(...)`             | ✔︎        | ⚠︎ (labels only)               | ✔︎                                  |         |
95//! | `fn id(...)`                 | ✔︎ (u32)  | ignored                       | ✔︎                                  |         |
96//! | `fn show(...)`               | ✔︎        | ✔︎                             | ✔︎                                  | ✔︎       |
97//! | `fn show_async(...)`         | ✔︎        |                               | ✔︎                                  |         |
98//! | `fn schedule(...)`           |          | ✔︎                             | ✔︎                                  |         |
99//!
100//! ## `NotificationHandle`
101//!
102//! | method                    | XDG | macOS (`NSUserNotifictation`) | macOS (`UNUserNotification`) | windows |
103//! |---------------------------|-----|-------------------------------|------------------------------|---------|
104//! | `fn wait_for_action(...)` | ✔︎   | ✔︎                             | ✔︎                            | ✔︎       |
105//! | `fn on_close(...)`        | ✔︎   | ✔︎                             | ✔︎                            | ✔︎       |
106//! | `fn close(...)`           | ✔︎   |                               | ✔︎                            |         |
107//! | `fn update(...)`          | ✔︎   |                               | ✔︎                            |         |
108//! | `fn id(...)`              | ✔︎   |                               | ✔︎                            |         |
109//!
110//! ## Functions
111//!
112//! |                                            | XDG | macOS | windows |
113//! |--------------------------------------------|-----|-------|---------|
114//! | `fn get_capabilities(...)`                 | ✔︎   |   -   |  -      |
115//! | `fn get_server_information(...)`           | ✔︎   |   -   |  -      |
116//! | `fn set_application(...)`                  | -   |   ✔︎   |  -      |
117//! | `fn get_bundle_identifier_or_default(...)` | -   |   ✔︎   |  -      |
118//!
119//!
120//! ### Toggles
121//!
122//! Please use `target_os` toggles if you plan on using methods labeled with -.
123//!
124//! ```ignore
125//! #[cfg(target_os = "macos")]
126//! // or
127//! // #### #[cfg(all(unix, not(target_os = "macos")))]
128//! ```
129//! </details>
130//!
131
132#![deny(
133    missing_copy_implementations,
134    trivial_casts,
135    trivial_numeric_casts,
136    unsafe_code,
137    unused_import_braces,
138    unused_qualifications
139)]
140#![warn(
141    missing_docs,
142    clippy::doc_markdown,
143    clippy::semicolon_if_nothing_returned,
144    clippy::single_match_else,
145    clippy::inconsistent_struct_constructor,
146    clippy::map_unwrap_or,
147    clippy::match_same_arms
148)]
149
150#[cfg(all(feature = "dbus", unix, not(target_os = "macos")))]
151extern crate dbus;
152
153#[cfg(target_os = "windows")]
154extern crate winrt_notification;
155
156#[macro_use]
157#[cfg(all(feature = "images_no_default_features", unix, not(target_os = "macos")))]
158extern crate lazy_static;
159
160pub mod error;
161mod hints;
162mod miniver;
163mod notification;
164mod notification_id;
165mod response;
166mod timeout;
167pub(crate) mod urgency;
168
169#[cfg(target_os = "macos")]
170mod macos;
171
172#[cfg(all(target_os = "macos", feature = "preview-macos-un"))]
173pub use mac_usernotifications::InterruptionLevel;
174
175#[cfg(target_os = "windows")]
176mod windows;
177
178#[cfg(all(unix, not(target_os = "macos")))]
179mod xdg;
180
181#[cfg(all(feature = "images_no_default_features", unix, not(target_os = "macos")))]
182mod image;
183
184#[cfg(all(target_os = "macos", not(feature = "preview-macos-un")))]
185pub use macos::NotificationHandle;
186#[cfg(target_os = "macos")]
187pub use macos::{get_bundle_identifier_or_default, set_application};
188
189#[cfg(all(target_os = "macos", feature = "preview-macos-un"))]
190pub use macos::{
191    check_bundle, get_notification_settings, get_notification_settings_blocking, request_auth,
192    request_auth_blocking, NotificationHandle,
193};
194
195#[cfg(all(
196    any(feature = "dbus", feature = "zbus"),
197    unix,
198    not(target_os = "macos")
199))]
200pub use crate::xdg::{
201    dbus_stack, get_capabilities, get_server_information, handle_action, DbusStack,
202    NotificationHandle,
203};
204
205// Cross-platform response types (available on all platforms).
206pub use crate::notification_id::NotificationId;
207pub use crate::response::ActionResponse;
208pub use crate::response::{CloseHandler, CloseReason, NotificationResponse, ResponseHandler};
209
210pub use crate::hints::Hint;
211
212#[cfg(all(feature = "images_no_default_features", unix, not(target_os = "macos")))]
213pub use crate::image::{Image, ImageError};
214
215#[cfg_attr(
216    all(target_os = "macos", not(feature = "preview-macos-un")),
217    deprecated(note = "Urgency is not supported on macOS (NSUserNotificationCenter path)")
218)]
219pub use crate::urgency::Urgency;
220
221pub use crate::{notification::Notification, timeout::Timeout};
222
223#[cfg(all(feature = "images_no_default_features", unix, not(target_os = "macos")))]
224lazy_static! {
225    /// Read once at runtime. Needed for images.
226    pub static ref SPEC_VERSION: miniver::Version =
227        get_server_information()
228        .and_then(|info| info.spec_version.parse::<miniver::Version>())
229        .unwrap_or_else(|_| miniver::Version::new(1,1));
230}
231
232/// Return value of [`get_server_information()`](crate::get_server_information).
233#[derive(Debug)]
234pub struct ServerInformation {
235    /// The product name of the server.
236    pub name: String,
237    /// The vendor name.
238    pub vendor: String,
239    /// The server's version string.
240    pub version: String,
241    /// The specification version the server is compliant with.
242    pub spec_version: String,
243}