commit
						7ab5bf643c
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -20,3 +20,4 @@ Cargo.lock | |||||||
| 
 | 
 | ||||||
| /target | /target | ||||||
| /.idea | /.idea | ||||||
|  | error.log | ||||||
|  | |||||||
| @ -1,8 +1,14 @@ | |||||||
| [package] | [package] | ||||||
| name = "snot" | name = "snot" | ||||||
| version = "0.1.1" | version = "0.1.3" | ||||||
| edition = "2021" | edition = "2021" | ||||||
| authors = ["candifloss <candifloss.cc>"] | authors = ["candifloss <candifloss.cc>"] | ||||||
|  | description = "Simple NOTification" | ||||||
|  | license = "GPL-3.0-or-later" | ||||||
|  | repository = "https://git.candifloss.cc/candifloss/SNot" | ||||||
|  | homepage = "https://git.candifloss.cc/candifloss/SNot" | ||||||
|  | documentation = "https://git.candifloss.cc/candifloss/SNot" | ||||||
|  | readme = "README.md" | ||||||
| 
 | 
 | ||||||
| [dependencies] | [dependencies] | ||||||
| zbus = "4.4.0" | zbus = "4.4.0" | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| // This module deals with converting the notification object into rson format, which can be used instead of json if preferred
 | // This module deals with converting the notification object into rson format, which can be used instead of json if preferred
 | ||||||
| use crate::notification::Notification; | use crate::notification::Notification; | ||||||
| use rson_rs::ser::to_string as rson_string; |  | ||||||
| use rson_rs::de::Error as RsonError; | use rson_rs::de::Error as RsonError; | ||||||
|  | use rson_rs::ser::to_string as rson_string; | ||||||
| 
 | 
 | ||||||
| impl Notification { | impl Notification { | ||||||
|     pub fn rson(&self) -> Result<String, RsonError> { |     pub fn rson(&self) -> Result<String, RsonError> { | ||||||
|         rson_string(self).map_err(|e| RsonError::Message(format!("RSON serialization error: {}", e))) |         rson_string(self).map_err(|e| RsonError::Message(format!("RSON serialization error: {e}"))) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,41 +1,87 @@ | |||||||
| use serde::{Serialize, Serializer}; | use serde::ser::{Serialize, SerializeMap, Serializer}; | ||||||
| /* | use serde_json::{Map, Value}; | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use std::hash::BuildHasher; | use zvariant::OwnedValue; | ||||||
| use zvariant::OwnedValue;   */ |  | ||||||
| 
 | 
 | ||||||
|  | /// Serialize actions
 | ||||||
|  | /// # Errors
 | ||||||
|  | /// Will return an empty map if there are no actions
 | ||||||
| pub fn serialize_actions<S>(actions: &[String], serializer: S) -> Result<S::Ok, S::Error> | pub fn serialize_actions<S>(actions: &[String], serializer: S) -> Result<S::Ok, S::Error> | ||||||
| where | where | ||||||
|     S: Serializer, |     S: Serializer, | ||||||
| { | { | ||||||
|     let mut map = serde_json::Map::new(); |     let mut map = Map::new(); | ||||||
| 
 | 
 | ||||||
|     // Assuming actions are in pairs: [id, label, id, label, ...]
 |     // Actions are in pairs: [id, label, id, label, ...]
 | ||||||
|     for chunk in actions.chunks(2) { |     for pair in actions.chunks(2) { | ||||||
|         if let [id, label] = chunk { |         if let [id, label] = pair { | ||||||
|             map.insert(id.clone(), serde_json::Value::String(label.clone())); |             map.insert(id.clone(), Value::String(label.clone())); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     map.serialize(serializer) |     map.serialize(serializer) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* | /// Serialize hints
 | ||||||
| pub fn serialize_hints<S, H>( | /// # Errors
 | ||||||
|     hints: &HashMap<String, OwnedValue, H>, | /// Will return an empty map if there are no hints
 | ||||||
|  | pub fn serialize_hints<S>( | ||||||
|  |     hints: &HashMap<String, OwnedValue>, | ||||||
|     serializer: S, |     serializer: S, | ||||||
| ) -> Result<S::Ok, S::Error> | ) -> Result<S::Ok, S::Error> | ||||||
| where | where | ||||||
|     S: Serializer, |     S: Serializer, | ||||||
|     H: BuildHasher, |  | ||||||
| { | { | ||||||
|     let mut map = serde_json::Map::new(); |     // Start serializing the map
 | ||||||
| 
 |     let mut map = serializer.serialize_map(Some(hints.len()))?; | ||||||
|     for (key, value) in hints { |     for (key, value) in hints { | ||||||
|         // Customize OwnedValue serialization as needed
 |         // Serialize each entry as desired
 | ||||||
|         map.insert(key.clone(), serde_json::Value::String(value.to_string())); |         map.serialize_entry(key, &HintValueSerializer(value))?; | ||||||
|  |     } | ||||||
|  |     map.end() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     map.serialize(serializer) | // A custom struct to handle serialization of OwnedValue
 | ||||||
|  | struct HintValueSerializer<'a>(&'a OwnedValue); | ||||||
|  | 
 | ||||||
|  | impl Serialize for HintValueSerializer<'_> { | ||||||
|  |     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||||
|  |     where | ||||||
|  |         S: Serializer, | ||||||
|  |     { | ||||||
|  |         let signature = self.0.value_signature().to_string(); // Get signature
 | ||||||
|  | 
 | ||||||
|  |         // Extract the raw value correctly
 | ||||||
|  |         let raw_value = if let Ok(v) = self.0.downcast_ref::<u8>() { | ||||||
|  |             Value::from(v) // BYTE: y
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<bool>() { | ||||||
|  |             Value::Bool(v) // BOOLEAN: b
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<i16>() { | ||||||
|  |             Value::from(v) // INT16: n
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<u16>() { | ||||||
|  |             Value::from(v) // UINT16: q
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<i32>() { | ||||||
|  |             Value::from(v) // INT32: i
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<u32>() { | ||||||
|  |             Value::from(v) // UINT32: u
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<i64>() { | ||||||
|  |             Value::from(v) // INT64: x
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<u64>() { | ||||||
|  |             Value::from(v) // UINT64: t
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<f64>() { | ||||||
|  |             Value::from(v) // DOUBLE: d
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<String>() { | ||||||
|  |             Value::String(v.clone()) // STRING: s
 | ||||||
|  |         } else if let Ok(v) = self.0.downcast_ref::<&str>() { | ||||||
|  |             Value::String(v.to_string()) // str
 | ||||||
|  |         } else { | ||||||
|  |             Value::Null // Unsupported types: fallback to Null
 | ||||||
|  |         }; // Not implemented: UNIX_FD: h, OBJECT_PATH: o, SIGNATURE: g
 | ||||||
|  | 
 | ||||||
|  |         // Serialize the final structure as a map
 | ||||||
|  |         let mut map = serializer.serialize_map(Some(2))?; | ||||||
|  |         map.serialize_entry("signature", &signature)?; | ||||||
|  |         map.serialize_entry("value", &raw_value)?; | ||||||
|  |         map.end() | ||||||
|  |     } | ||||||
| } | } | ||||||
| */ |  | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -13,8 +13,8 @@ use futures_util::stream::TryStreamExt; | |||||||
| use zbus::{message::Body, Connection, Result}; | use zbus::{message::Body, Connection, Result}; | ||||||
| 
 | 
 | ||||||
| const SERVER_NAME: &str = "SNot"; // Server software name
 | const SERVER_NAME: &str = "SNot"; // Server software name
 | ||||||
| const VENDOR: &str = "candifloss.cc"; // Server software vendor
 | const VENDOR: &str = env!("CARGO_PKG_AUTHORS"); // Server software vendor
 | ||||||
| const VERSION: &str = "0.1.2"; // Server software version
 | const VERSION: &str = env!("CARGO_PKG_VERSION"); // Server software version, from Cargo.toml
 | ||||||
| const SPEC_VERSION: &str = "0.42"; // DBus specification version
 | const SPEC_VERSION: &str = "0.42"; // DBus specification version
 | ||||||
| const NOTIF_INTERFACE: &str = "org.freedesktop.Notifications"; // DBus interface name
 | const NOTIF_INTERFACE: &str = "org.freedesktop.Notifications"; // DBus interface name
 | ||||||
| 
 | 
 | ||||||
| @ -109,7 +109,7 @@ async fn main() -> Result<()> { | |||||||
|                 } |                 } | ||||||
|                 "GetCapabilities" => { |                 "GetCapabilities" => { | ||||||
|                     // Client requested server capabilities. Respond with the supported capabilities
 |                     // Client requested server capabilities. Respond with the supported capabilities
 | ||||||
|                     let capabilities = vec!["actions", "body", "body-hyperlinks"]; // Add more LATER
 |                     let capabilities = vec![/*"actions",*/ "body", "body-hyperlinks"]; // Add more LATER
 | ||||||
|                     connection.reply(&msg, &capabilities).await?; |                     connection.reply(&msg, &capabilities).await?; | ||||||
|                     if verbose { |                     if verbose { | ||||||
|                         println!("Request received: {member}\n\tCapabilities: {capabilities:?}"); |                         println!("Request received: {member}\n\tCapabilities: {capabilities:?}"); | ||||||
| @ -134,8 +134,8 @@ async fn main() -> Result<()> { | |||||||
|                         "r" => { |                         "r" => { | ||||||
|                             // Print the rson version
 |                             // Print the rson version
 | ||||||
|                             match notif.rson() { |                             match notif.rson() { | ||||||
|                                 Ok(rson_string) => println!("{}", rson_string), |                                 Ok(rson_string) => println!("{rson_string}"), | ||||||
|                                 Err(e) => eprintln!("Failed to convert to RSON: {}", e), |                                 Err(e) => eprintln!("Failed to convert to RSON: {e}"), | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         "p" => { |                         "p" => { | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| use crate::formats::serde::serialize_actions; | use crate::formats::serde::{serialize_actions, serialize_hints}; | ||||||
| use serde::Serialize; | use serde::Serialize; | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use zbus::{message::Body, Result}; | use zbus::{message::Body, Result}; | ||||||
| @ -21,7 +21,7 @@ pub struct Notification { | |||||||
|     #[serde(serialize_with = "serialize_actions")] |     #[serde(serialize_with = "serialize_actions")] | ||||||
|     actions: Vec<String>, |     actions: Vec<String>, | ||||||
|     // Useful extra data - notif type, urgency, notif sound, icon data, etc.
 |     // Useful extra data - notif type, urgency, notif sound, icon data, etc.
 | ||||||
|     //#[serde(serialize_with = "serialize_hints")]
 |     #[serde(serialize_with = "serialize_hints")] | ||||||
|     hints: HashMap<String, OwnedValue>, |     hints: HashMap<String, OwnedValue>, | ||||||
|     // Seconds till this notif expires. Optional
 |     // Seconds till this notif expires. Optional
 | ||||||
|     expir_timeout: i32, |     expir_timeout: i32, | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user