From 09afdf51a45cd8a69c40a4f5a6a66141ddc9e4a6 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Sat, 16 May 2020 23:05:14 +0100 Subject: [PATCH] Add DBUS stubs for a basic Channel type --- src/padfoot.rs | 3 ++ src/padfoot/channel.rs | 54 +++++++++++++++++++++++ src/padfoot/channel/channel.rs | 73 ++++++++++++++++++++++++++++++++ src/padfoot/channel/messages.rs | 52 +++++++++++++++++++++++ src/padfoot/channel/type_text.rs | 43 +++++++++++++++++++ src/padfoot/protocol.rs | 13 +++--- 6 files changed, 233 insertions(+), 5 deletions(-) create mode 100644 src/padfoot/channel.rs create mode 100644 src/padfoot/channel/channel.rs create mode 100644 src/padfoot/channel/messages.rs create mode 100644 src/padfoot/channel/type_text.rs diff --git a/src/padfoot.rs b/src/padfoot.rs index 5991558..a7a9e16 100644 --- a/src/padfoot.rs +++ b/src/padfoot.rs @@ -1,3 +1,6 @@ +mod channel; +pub use self::channel::*; + mod connection; pub use self::connection::*; diff --git a/src/padfoot/channel.rs b/src/padfoot/channel.rs new file mode 100644 index 0000000..b1a9651 --- /dev/null +++ b/src/padfoot/channel.rs @@ -0,0 +1,54 @@ +#[allow(clippy::module_inception)] +mod channel; +pub use channel::*; + +mod messages; +pub use messages::*; + +mod type_text; +pub use type_text::*; + +use crate::telepathy; + +// FIXME: I'm assuming that all channels will be of type text and 1-1 for now. +#[derive(Debug)] +pub struct Channel { +} + +// "This SHOULD NOT include the channel type and channel interface itself" +pub fn channel_interfaces() -> Vec { + vec![ + "org.freedesktop.Telepathy.Channel.Interface.Messages".to_string(), + ] +} + +type Result = std::result::Result; + +impl Channel { + fn build_tree(self) -> dbus::tree::Tree { + let c_rc = std::rc::Rc::new(self); + let f = dbus::tree::Factory::new_fn::<()>(); + let mut tree = f.tree(()); + + let c_rc1 = c_rc.clone(); + let chan_iface = telepathy::channel_server(&f, (), move |_| c_rc1.clone()); + + let c_rc2 = c_rc.clone(); + let messages_iface = + telepathy::channel_interface_messages_server(&f, (), move |_| c_rc2.clone()); + + let type_text_iface = + telepathy::channel_type_text_server(&f, (), move |_| c_rc.clone()); + + tree = tree.add( + f.object_path("", ()) + .introspectable() + .add(chan_iface) + .add(messages_iface) + .add(type_text_iface), + ); + tree = tree.add(f.object_path("/", ()).introspectable()); + + tree + } +} diff --git a/src/padfoot/channel/channel.rs b/src/padfoot/channel/channel.rs new file mode 100644 index 0000000..751b0ae --- /dev/null +++ b/src/padfoot/channel/channel.rs @@ -0,0 +1,73 @@ +use crate::telepathy; + +use dbus::tree::MethodErr; + +use super::{Channel, Result}; + +impl AsRef for std::rc::Rc { + fn as_ref(&self) -> &(dyn telepathy::Channel + 'static) { + &**self + } +} + +impl telepathy::Channel for Channel { + fn close(&self) -> Result<()> { + println!("Channel::close()"); + Err(MethodErr::no_arg()) + } + + fn get_channel_type(&self) -> Result { + self.channel_type() + } + + fn get_handle(&self) -> Result<(u32, u32)> { + println!("Channel::get_handle()"); + Err(MethodErr::no_arg()) + } + + fn get_interfaces(&self) -> Result> { + println!("Channel::get_interfaces()"); + Err(MethodErr::no_arg()) + } + + fn channel_type(&self) -> Result { + println!("Channel::channel_type()"); + + Ok("org.freedesktop.Telepathy.Channel.Text".to_string()) + } + + fn interfaces(&self) -> Result> { + println!("Channel::interfaces()"); + Ok(super::channel_interfaces()) + } + + fn target_handle(&self) -> Result { + println!("Channel::target_handle()"); + Err(MethodErr::no_arg()) + } + + fn target_id(&self) -> Result { + println!("Channel::target_id()"); + Err(MethodErr::no_arg()) + } + + fn target_handle_type(&self) -> Result { + println!("Channel::target_handle_type()"); + Err(MethodErr::no_arg()) + } + + fn requested(&self) -> Result { + println!("Channel::requested()"); + Err(MethodErr::no_arg()) + } + + fn initiator_handle(&self) -> Result { + println!("Channel::initiator_handle()"); + Err(MethodErr::no_arg()) + } + + fn initiator_id(&self) -> Result { + println!("Channel::initiator_id()"); + Err(MethodErr::no_arg()) + } +} diff --git a/src/padfoot/channel/messages.rs b/src/padfoot/channel/messages.rs new file mode 100644 index 0000000..2e8e326 --- /dev/null +++ b/src/padfoot/channel/messages.rs @@ -0,0 +1,52 @@ +use crate::padfoot::VarArg; +use crate::telepathy; + +use dbus::tree::MethodErr; +use std::collections::HashMap; + +use super::{Channel, Result}; + +impl AsRef for std::rc::Rc { + fn as_ref(&self) -> &(dyn telepathy::ChannelInterfaceMessages + 'static) { + &**self + } +} + +impl telepathy::ChannelInterfaceMessages for Channel { + fn send_message(&self, message: Vec>, flags: u32) -> Result { + println!("Channel::send_message({:?}, {})", message, flags); + Err(MethodErr::no_arg()) + } + + fn get_pending_message_content(&self, message_id: u32, parts: Vec) -> Result> { + println!("Channel::get_pending_message_content({}, {:?})", message_id, parts); + Err(MethodErr::no_arg()) + } + + fn supported_content_types(&self) -> Result> { + println!("Channel::supported_content_types()"); + Err(MethodErr::no_arg()) + } + + fn message_types(&self) -> Result> { + println!("Channel::message_types()"); + Err(MethodErr::no_arg()) + + } + + fn message_part_support_flags(&self) -> Result { + println!("Channel::message_part_support_flags()"); + Err(MethodErr::no_arg()) + } + + fn pending_messages(&self) -> Result>>> { + println!("Channel::pending_messages()"); + Err(MethodErr::no_arg()) + + } + + fn delivery_reporting_support(&self) -> Result { + println!("Channel::delivery_reporting_support()"); + Err(MethodErr::no_arg()) + } +} diff --git a/src/padfoot/channel/type_text.rs b/src/padfoot/channel/type_text.rs new file mode 100644 index 0000000..7a38042 --- /dev/null +++ b/src/padfoot/channel/type_text.rs @@ -0,0 +1,43 @@ +use crate::telepathy; +use dbus::tree::MethodErr; + +use super::{Channel, Result}; + +impl AsRef for std::rc::Rc { + fn as_ref(&self) -> &(dyn telepathy::ChannelTypeText + 'static) { + &**self + } +} + +type PendingMessagesSpec = ( + u32, // numeric identifier + u32, // Unix timestamp indicating when the message was received + u32, // contact handle for the contact who sent the message + u32, // message type, taken from ChannelTextMessageType + u32, // bitwise-OR of the message flags from ChannelTextMessageFlags + String, // text of the message +); + +// Most of these methods are deprecated, so should be implemented in terms of +// the mandatory Messages interface. +impl telepathy::ChannelTypeText for Channel { + fn acknowledge_pending_messages(&self, ids: Vec) -> Result<()> { + println!("Channel::acknowledge_pending_messages({:?})", ids); + Err(MethodErr::no_arg()) + } + + fn get_message_types(&self) -> Result> { + println!("Channel::get_message_types()"); + Err(MethodErr::no_arg()) + } + + fn list_pending_messages(&self, clear: bool) -> Result> { + println!("Channel::list_pending_messages({})", clear); + Err(MethodErr::no_arg()) + } + + fn send(&self, message_type: u32, text: &str) -> Result<()> { + println!("Channel::send({}, {})", message_type, text); + Err(MethodErr::no_arg()) + } +} diff --git a/src/padfoot/protocol.rs b/src/padfoot/protocol.rs index d5fa07a..566ee89 100644 --- a/src/padfoot/protocol.rs +++ b/src/padfoot/protocol.rs @@ -15,10 +15,10 @@ pub const PROTO_NAME: &str = "delta"; pub struct Protocol {} pub type ParamSpec = ( - String, // Name - u32, // Flags (Conn_Mgr_Param_Flags) - String, // Signature - VarArg, // Default value + String, // Name + u32, // Flags (Conn_Mgr_Param_Flags) + String, // Signature + VarArg, // Default value ); // Requestable_Channel_Class @@ -67,7 +67,10 @@ pub fn requestables() -> Vec { var_str("org.freedesktop.Telepathy.Channel.Type.Text".to_string()), ); - rf.insert("org.freedesktop.Telepathy.Channel.TargetHandleType".to_string(), var_u32(1)); + rf.insert( + "org.freedesktop.Telepathy.Channel.TargetHandleType".to_string(), + var_u32(1), + ); let ra = vec![ "org.freedesktop.Telepathy.Channel.TargetHandle".to_string(),