diff --git a/Cargo.toml b/Cargo.toml index e6d9fae..107da19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,8 @@ authors = ["candifloss "] [dependencies] zbus = "4.4.0" -zbus_names = "*" +zbus_macros = "4.4.0" +zbus_names = "3.0.0" +zvariant = "4.2.0" # rson_rs = "0.2.1" -tokio = "1.39.3" \ No newline at end of file +tokio = { version = "1.39.3", features = ["full"] } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index bcd6f03..5861cba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,46 +1,114 @@ use std::collections::HashMap; -use zbus::blocking::{Connection, MessageIterator}; +use zbus::Connection; +use zbus::blocking::MessageIterator; use zbus::fdo::Result; use zbus::zvariant::Value; use zbus::MatchRule; +use zbus_names::InterfaceName; +use zbus_names::WellKnownName; +use std::fmt; +//use tokio; + +fn print_type_of(_: &T) { + println!("{}", std::any::type_name::()); +} + +// Actions field of notication +struct NotifAction<'a> { + action_id: &'a str, + action: &'a str, +} + +impl fmt::Display for NotifAction<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "{}: {}", &self.action_id, &self.action)?; + + Ok(()) + } +} + +// Structure of a notification +struct Notif<'a> { + app_name: &'a str, + replace_id: u32, + ico: &'a str, + summary: &'a str, + body: &'a str, + actions: &'a [&'a str], + hints: HashMap<&'a str, &'a zbus::zvariant::Value<'a >>, + expir_timeout: i32, +} + +// Function to print the contents of the notification +impl fmt::Display for Notif<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "AppName: {}", &self.app_name)?; + writeln!(f, "ReplaceId: {}", &self.replace_id)?; + write!( + f, + "Icon: {}\nSummary: {}\nBody: {}\nActions:\n", + &self.ico, &self.summary, &self.body + )?; + + let actions_len = self.actions.len(); + let i = 0; + + while i < actions_len { + let a:NotifAction; + a.action_id = &self.actions[i]; + a.action = &self.actions[i+1]; + println!("{a}"); + i += 1; + }; + writeln!(f, "Hints:")?; + for (key, value) in &self.hints { + writeln!(f, "\t{key}: {value}")?; + } + match self.expir_timeout { + -1 => writeln!(f, "None")?, + Some(millisec) => writeln!(f, "Expiration Timeout: {millisec}")?, + None => writeln!(f, "Error getting timeout")?, + } + Ok(()) // Return Ok to indicate success + } +} + +#[tokio::main] +async fn main() -> Result<()> { + + let interface = InterfaceName::try_from("org.freedesktop.Notifications").unwrap(); + let busname = WellKnownName::try_from("org.freedesktop.Notifications").unwrap(); -fn main() -> Result<()> { // Establish a connection to the session bus - let connection = Connection::session()?; + let connection = Connection::session().await?; // Create a match rule for the Notify signal - let match_rule = MatchRule::builder() + /*let match_rule = MatchRule::builder() .msg_type(zbus::message::Type::Signal) + .sender("org.freedesktop.Notifications")? .interface("org.freedesktop.Notifications")? + .arg_path(0, "/org/freedesktop/Notifications")? .member("Notify")? - .build(); + .build();*/ // Create a message iterator for the match rule - let mut iterator = MessageIterator::for_match_rule(match_rule, &connection, None)?; + //let mut iterator = MessageIterator::for_match_rule(match_rule, &connection, None)?; // Loop to handle incoming messages - while let Some(result) = iterator.next() { - match result { - Ok(msg) => { - // Extract the body of the message - let body_result: Result<(String, u32, String, String, String, Vec, HashMap, i32), _> = msg.body(); - - match body_result { - Ok((app_name, id, summary, body, icon, actions, hints, timeout)) => { - println!("Got notification:"); - println!(" App Name: {}", app_name); - println!(" ID: {}", id); - println!(" Summary: {}", summary); - println!(" Body: {}", body); - println!(" Icon: {}", icon); - println!(" Actions: {:?}", actions); - println!(" Hints: {:?}", hints); - println!(" Timeout: {}", timeout); - }, - Err(e) => println!("Error decoding message body: {:?}", e), - } + loop { + let msg = connection.receive_message()?; + let msg_header = msg.header()?; + dbg!(&msg); + + match msg_header.message_type()? { + zbus::message::Type::Signal => { + // real code would check msg_header path(), interface() and member() + // handle invalid calls, introspection, errors etc + let arg: &str = msg.body()?; + println!("Msg.body: {arg}"); + //connection.reply(&msg, &(format!("Hello {}!", arg)))?; } - Err(e) => println!("Error receiving message: {:?}", e), + _ => continue, } }