2015-03-10 07:46:54 +00:00
|
|
|
//! Rustic bindings to [libnotify](https://developer.gnome.org/libnotify/)
|
|
|
|
//!
|
|
|
|
//! ```rust
|
2015-11-03 08:15:16 +00:00
|
|
|
//! extern crate libnotify;
|
2015-11-02 23:50:27 +00:00
|
|
|
//!
|
2015-11-03 08:15:16 +00:00
|
|
|
//! fn main() {
|
|
|
|
//! let notify = libnotify::Context::new("hello").unwrap_or_else(|e| {
|
|
|
|
//! panic!("{}", e);
|
|
|
|
//! });
|
|
|
|
//! let body_text = Some("This is the optional body text.");
|
|
|
|
//! let n = notify.new_notification("This is the summary.", body_text, None)
|
|
|
|
//! .unwrap_or_else(|e| panic!("{}", e));
|
|
|
|
//! n.show().unwrap_or_else(|e| panic!("{}", e));
|
|
|
|
//! }
|
2015-03-10 07:46:54 +00:00
|
|
|
//!
|
|
|
|
//! ```
|
|
|
|
|
2015-11-02 23:51:20 +00:00
|
|
|
#![warn(missing_docs)]
|
|
|
|
|
2015-03-25 18:04:43 +00:00
|
|
|
extern crate libnotify_sys as sys;
|
|
|
|
extern crate glib_2_0_sys as glib;
|
2015-09-19 07:42:17 +00:00
|
|
|
extern crate gtypes;
|
2015-03-07 12:55:19 +00:00
|
|
|
|
2015-11-03 00:01:49 +00:00
|
|
|
use std::ffi::{self, CStr, CString};
|
2015-03-07 13:21:17 +00:00
|
|
|
use std::marker::PhantomData;
|
2015-03-10 18:14:18 +00:00
|
|
|
use std::fmt;
|
2015-11-02 23:49:12 +00:00
|
|
|
use std::error::Error;
|
2015-03-07 12:55:19 +00:00
|
|
|
|
2015-11-02 22:55:35 +00:00
|
|
|
use gtypes::{TRUE, FALSE};
|
2015-03-07 12:55:19 +00:00
|
|
|
|
|
|
|
/// Error that can happen on context creation
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ContextCreationError {
|
2015-11-02 23:52:13 +00:00
|
|
|
/// Context already exists.
|
2015-03-07 12:55:19 +00:00
|
|
|
AlreadyExists,
|
2015-11-02 23:52:13 +00:00
|
|
|
/// Failed to initialize libnotify.
|
|
|
|
InitError,
|
2015-11-03 00:01:49 +00:00
|
|
|
/// A nul byte was found in the provided string.
|
|
|
|
NulError(ffi::NulError),
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 18:14:18 +00:00
|
|
|
impl fmt::Display for ContextCreationError {
|
2015-11-02 23:55:09 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-03-10 18:14:18 +00:00
|
|
|
use ContextCreationError::*;
|
|
|
|
match *self {
|
|
|
|
AlreadyExists => write!(f, "A Libnotify context already exists."),
|
2015-11-02 23:52:13 +00:00
|
|
|
InitError => write!(f, "Failed to initialize libnotify."),
|
2015-11-03 00:01:49 +00:00
|
|
|
NulError(ref e) => write!(f, "{}", e),
|
2015-03-10 18:14:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-03 08:15:16 +00:00
|
|
|
impl From<ffi::NulError> for ContextCreationError {
|
|
|
|
fn from(src: ffi::NulError) -> Self {
|
|
|
|
ContextCreationError::NulError(src)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-07 12:55:19 +00:00
|
|
|
#[derive(Debug)]
|
2015-11-03 00:04:22 +00:00
|
|
|
/// An error that can happen when attempting to create a notification.
|
2015-03-07 12:55:19 +00:00
|
|
|
pub enum NotificationCreationError {
|
2015-11-03 00:01:49 +00:00
|
|
|
/// A nul byte was found in the provided string.
|
|
|
|
NulError(ffi::NulError),
|
|
|
|
/// An unknown error happened.
|
2015-11-02 22:55:35 +00:00
|
|
|
Unknown,
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
|
2015-03-10 18:14:18 +00:00
|
|
|
impl fmt::Display for NotificationCreationError {
|
2015-11-02 23:55:09 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-03-10 18:14:18 +00:00
|
|
|
use NotificationCreationError::*;
|
|
|
|
match *self {
|
2015-11-03 00:01:49 +00:00
|
|
|
NulError(ref e) => write!(f, "{}", e),
|
2015-11-02 22:55:35 +00:00
|
|
|
Unknown => write!(f, "Unknown error"),
|
2015-03-10 18:14:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-03 08:15:16 +00:00
|
|
|
impl From<ffi::NulError> for NotificationCreationError {
|
|
|
|
fn from(src: ffi::NulError) -> Self {
|
|
|
|
NotificationCreationError::NulError(src)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-08 16:11:44 +00:00
|
|
|
/// The context which within libnotify operates.
|
|
|
|
///
|
|
|
|
/// Only one context can exist at a time.
|
2015-03-07 12:55:19 +00:00
|
|
|
pub struct Context;
|
|
|
|
|
|
|
|
impl Context {
|
2015-03-08 16:07:50 +00:00
|
|
|
/// Create a new context
|
|
|
|
///
|
|
|
|
/// Arguments:
|
|
|
|
///
|
|
|
|
/// - app_name: The name of the application using the context
|
2015-03-07 12:55:19 +00:00
|
|
|
pub fn new(app_name: &str) -> Result<Context, ContextCreationError> {
|
|
|
|
unsafe {
|
|
|
|
if sys::notify_is_initted() == TRUE {
|
|
|
|
return Err(ContextCreationError::AlreadyExists);
|
|
|
|
}
|
2015-11-03 08:15:16 +00:00
|
|
|
let app_name = try!(CString::new(app_name));
|
2015-03-07 12:55:19 +00:00
|
|
|
if sys::notify_init(app_name.as_ptr()) == FALSE {
|
2015-11-02 23:52:13 +00:00
|
|
|
return Err(ContextCreationError::InitError);
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(Context)
|
|
|
|
}
|
2015-03-08 16:07:50 +00:00
|
|
|
/// Creates a new Notification.
|
|
|
|
///
|
|
|
|
/// Arguments:
|
|
|
|
///
|
|
|
|
/// - summary: Required summary text
|
|
|
|
/// - body: Optional body text
|
|
|
|
/// - icon: Optional icon theme icon name or filename
|
2015-11-02 22:55:35 +00:00
|
|
|
pub fn new_notification(&self,
|
|
|
|
summary: &str,
|
|
|
|
body: Option<&str>,
|
|
|
|
icon: Option<&str>)
|
|
|
|
-> Result<Notification, NotificationCreationError> {
|
2015-11-03 08:15:16 +00:00
|
|
|
let summary = try!(CString::new(summary));
|
2015-03-08 15:59:15 +00:00
|
|
|
let body = match body {
|
2015-11-03 08:15:16 +00:00
|
|
|
Some(body) => Some(try!(CString::new(body))),
|
2015-11-02 22:55:35 +00:00
|
|
|
None => None,
|
2015-03-08 15:59:15 +00:00
|
|
|
};
|
|
|
|
let body_ptr = match body {
|
|
|
|
Some(body) => body.as_ptr(),
|
2015-11-02 22:55:35 +00:00
|
|
|
None => std::ptr::null(),
|
2015-03-08 15:59:15 +00:00
|
|
|
};
|
|
|
|
let icon = match icon {
|
2015-11-03 08:15:16 +00:00
|
|
|
Some(icon) => Some(try!(CString::new(icon))),
|
2015-11-02 22:55:35 +00:00
|
|
|
None => None,
|
2015-03-08 15:59:15 +00:00
|
|
|
};
|
|
|
|
let icon_ptr = match icon {
|
|
|
|
Some(icon) => icon.as_ptr(),
|
2015-11-02 22:55:35 +00:00
|
|
|
None => std::ptr::null(),
|
2015-03-07 12:55:19 +00:00
|
|
|
};
|
|
|
|
unsafe {
|
2015-11-02 22:55:35 +00:00
|
|
|
let n = sys::notify_notification_new(summary.as_ptr(), body_ptr, icon_ptr);
|
2015-03-07 12:55:19 +00:00
|
|
|
if n.is_null() {
|
|
|
|
return Err(NotificationCreationError::Unknown);
|
|
|
|
}
|
|
|
|
|
2015-11-02 22:55:35 +00:00
|
|
|
Ok(Notification {
|
|
|
|
handle: n,
|
|
|
|
_phantom: PhantomData,
|
|
|
|
})
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Drop for Context {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
unsafe {
|
|
|
|
sys::notify_uninit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-08 16:07:50 +00:00
|
|
|
/// A passive pop-up notification
|
2015-03-07 13:21:17 +00:00
|
|
|
pub struct Notification<'a> {
|
|
|
|
handle: *mut sys::NotifyNotification,
|
2015-11-02 22:55:35 +00:00
|
|
|
_phantom: PhantomData<&'a Context>,
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
|
2015-03-07 13:21:17 +00:00
|
|
|
impl<'a> Notification<'a> {
|
2015-03-08 16:07:50 +00:00
|
|
|
/// Tells the notification server to display the notification
|
|
|
|
/// on the screen.
|
2015-11-02 23:49:12 +00:00
|
|
|
pub fn show(&'a self) -> Result<(), NotificationShowError> {
|
2015-03-07 12:55:19 +00:00
|
|
|
unsafe {
|
|
|
|
let mut err: *mut glib::GError = std::ptr::null_mut();
|
|
|
|
sys::notify_notification_show(self.handle, &mut err);
|
|
|
|
if !err.is_null() {
|
2015-11-02 23:49:12 +00:00
|
|
|
let result = Err(NotificationShowError {
|
|
|
|
message: CStr::from_ptr((*err).message).to_string_lossy().into_owned(),
|
|
|
|
});
|
2015-03-07 12:55:19 +00:00
|
|
|
glib::g_error_free(err);
|
2015-11-02 23:49:12 +00:00
|
|
|
return result;
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
2015-11-02 22:55:35 +00:00
|
|
|
return Ok(());
|
2015-03-07 12:55:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-02 23:49:12 +00:00
|
|
|
|
2015-11-03 00:04:22 +00:00
|
|
|
/// An error that can happen when attempting to show a notification.
|
2015-11-02 23:49:12 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct NotificationShowError {
|
|
|
|
message: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Display for NotificationShowError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "Error showing notification: {}", self.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for NotificationShowError {
|
|
|
|
fn description(&self) -> &str {
|
|
|
|
"Notification show error"
|
|
|
|
}
|
|
|
|
}
|