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}