From a231712057b5e24b86612bba9bd662380d19f147 Mon Sep 17 00:00:00 2001 From: szymon Date: Sat, 3 Oct 2026 12:43:34 +0200 Subject: [PATCH] feat: add libnotify error --- Cargo.lock | 2 +- src/api/errors.rs | 37 +++++++++++++++++++++++++++++++++++++ src/api/functions.rs | 19 ++++++++++--------- src/api/mod.rs | 2 ++ src/wrappers/context.rs | 9 ++++++--- 5 files changed, 56 insertions(+), 13 deletions(-) create mode 100644 src/api/errors.rs diff --git a/Cargo.lock b/Cargo.lock index 4138772..777bfdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,7 +247,7 @@ dependencies = [ [[package]] name = "libnotify-rs" -version = "0.2.0" +version = "0.2.1" dependencies = [ "bindgen", "glib", diff --git a/src/api/errors.rs b/src/api/errors.rs new file mode 100644 index 0000000..98aabc1 --- /dev/null +++ b/src/api/errors.rs @@ -0,0 +1,37 @@ +/// Enum mapping every possible error that can happen in this lib, with a nice enum. +#[derive(Debug)] +pub enum LibnotifyError { + /// [libnotify init](https://gnome.pages.gitlab.gnome.org/libnotify/func.init.html) failed + InitFail, + /// `&str` contains a null terminator. Read more at [std documentation](https://doc.rust-lang.org/std/ffi/struct.NulError.html) + NulError(std::ffi::NulError), +} + +impl std::fmt::Display for LibnotifyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::InitFail => { + write!(f, "Libnotify failed to init") + } + + Self::NulError(_) => { + write!(f, "Argument contains a null terminator") + } + } + } +} + +impl std::error::Error for LibnotifyError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::InitFail => None, + Self::NulError(e) => Some(e), + } + } +} + +impl From for LibnotifyError { + fn from(value: std::ffi::NulError) -> Self { + Self::NulError(value) + } +} diff --git a/src/api/functions.rs b/src/api/functions.rs index c716336..fcf7ffc 100644 --- a/src/api/functions.rs +++ b/src/api/functions.rs @@ -1,3 +1,5 @@ +use crate::api::errors::LibnotifyError; + use super::utils::c_str_to_rs_str_and_free; use super::libnotify::*; @@ -10,7 +12,7 @@ use super::libnotify::*; /// Initialized libnotify. This must be called before any other functions. /// /// Starting from 0.8, if the provided app_name is NULL, libnotify will try to figure it out from the running application. Before it was not allowed, and was causing libnotify not to be initialized. -pub fn init<'a, T>(app_name: T) -> Result<(), Box> +pub fn init<'a, T>(app_name: T) -> Result<(), LibnotifyError> where T: Into>, { @@ -24,7 +26,7 @@ where ) } == 0 { - return Err("Libnotify init failed".into()); + return Err(LibnotifyError::InitFail); } Ok(()) @@ -161,7 +163,7 @@ pub fn get_server_info() -> Option { */ /// Sets the application name -pub fn set_app_name(app_name: &str) -> Result<(), std::ffi::NulError> { +pub fn set_app_name(app_name: &str) -> Result<(), LibnotifyError> { let app_name_c = std::ffi::CString::new(app_name)?; unsafe { notify_set_app_name(app_name_c.as_ptr()) }; @@ -172,7 +174,7 @@ pub fn set_app_name(app_name: &str) -> Result<(), std::ffi::NulError> { /// Available since: 0.8.4 /// /// app_icon is icon name or path to an image -pub fn set_app_icon(app_icon: &str) -> Result<(), std::ffi::NulError> { +pub fn set_app_icon(app_icon: &str) -> Result<(), LibnotifyError> { let app_icon_c = std::ffi::CString::new(app_icon)?; unsafe { notify_set_app_icon(app_icon_c.as_ptr()) }; @@ -195,11 +197,10 @@ mod tests { #[test] fn test_bad_init() { - assert!( - init("Mor\0ius") - .unwrap_err() - .is::() - ); + assert!(matches!( + init("Mor\0ius").unwrap_err(), + LibnotifyError::NulError(_) + )); } #[test] diff --git a/src/api/mod.rs b/src/api/mod.rs index 15241f4..ed18bb0 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,3 +1,5 @@ +/// Custom error types +pub mod errors; /// Same as [libnotify global functions](https://gnome.pages.gitlab.gnome.org/libnotify/index.html#functions) pub mod functions; mod libnotify; diff --git a/src/wrappers/context.rs b/src/wrappers/context.rs index 7bddcb9..12c1c65 100644 --- a/src/wrappers/context.rs +++ b/src/wrappers/context.rs @@ -1,4 +1,7 @@ -use crate::api::functions::{init, is_initted, set_app_icon, set_app_name, uninit}; +use crate::api::{ + errors::LibnotifyError, + functions::{init, is_initted, set_app_icon, set_app_name, uninit}, +}; /// Notification context. Handles libnotify initializing and uninitializing. pub struct LibnotifyContext {} @@ -25,13 +28,13 @@ impl LibnotifyContext { } /// Sets global app name - pub fn set_new_name(&self, app_name: &str) -> Result<(), std::ffi::NulError> { + pub fn set_new_name(&self, app_name: &str) -> Result<(), LibnotifyError> { set_app_name(app_name)?; Ok(()) } /// Sets global app icon - pub fn set_app_icon(&self, app_icon: &str) -> Result<(), std::ffi::NulError> { + pub fn set_app_icon(&self, app_icon: &str) -> Result<(), LibnotifyError> { set_app_icon(app_icon)?; Ok(()) }