Skip to content

Commit

Permalink
✨ zb,zm: Support SignalEmitter<'_> in property getters
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvncj committed Dec 22, 2024
1 parent 279b7a7 commit 8e4a9df
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 28 deletions.
3 changes: 2 additions & 1 deletion zbus/src/fdo/object_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl ObjectManager {
&self,
#[zbus(object_server)] server: &ObjectServer,
#[zbus(connection)] connection: &Connection,
#[zbus(signal_emitter)] emitter: SignalEmitter<'_>,
#[zbus(header)] header: Header<'_>,
) -> Result<ManagedObjects> {
let path = header.path().ok_or(crate::Error::MissingField)?;
Expand All @@ -58,7 +59,7 @@ impl ObjectManager {
.get_child(path)
.ok_or_else(|| Error::UnknownObject(format!("Unknown object '{path}'")))?;

node.get_managed_objects(server, connection).await
node.get_managed_objects(server, &emitter, connection).await
}

/// This signal is emitted when either a new object is added or when an existing object gains
Expand Down
6 changes: 4 additions & 2 deletions zbus/src/fdo/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ impl Properties {
#[zbus(connection)] conn: &Connection,
#[zbus(object_server)] server: &ObjectServer,
#[zbus(header)] header: Header<'_>,
#[zbus(signal_emitter)] emitter: SignalEmitter<'_>,
) -> Result<OwnedValue> {
let path = header.path().ok_or(crate::Error::MissingField)?;
let root = server.root().read().await;
Expand All @@ -46,7 +47,7 @@ impl Properties {
.instance
.read()
.await
.get(property_name, server, conn, Some(&header))
.get(property_name, server, conn, &emitter, Some(&header))
.await;
res.unwrap_or_else(|| {
Err(Error::UnknownProperty(format!(
Expand Down Expand Up @@ -120,6 +121,7 @@ impl Properties {
interface_name: InterfaceName<'_>,
#[zbus(object_server)] server: &ObjectServer,
#[zbus(connection)] connection: &Connection,
#[zbus(signal_emitter)] emitter: SignalEmitter<'_>,
#[zbus(header)] header: Header<'_>,
) -> Result<HashMap<String, OwnedValue>> {
let path = header.path().ok_or(crate::Error::MissingField)?;
Expand All @@ -135,7 +137,7 @@ impl Properties {
.instance
.read()
.await
.get_all(server, connection, Some(&header))
.get_all(server, connection, &emitter, Some(&header))
.await?;
Ok(res)
}
Expand Down
2 changes: 2 additions & 0 deletions zbus/src/object_server/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ pub trait Interface: Any + Send + Sync {
property_name: &str,
server: &ObjectServer,
connection: &Connection,
emitter: &SignalEmitter<'_>,
header: Option<&message::Header<'_>>,
) -> Option<fdo::Result<OwnedValue>>;

Expand All @@ -66,6 +67,7 @@ pub trait Interface: Any + Send + Sync {
&self,
object_server: &ObjectServer,
connection: &Connection,
emitter: &SignalEmitter<'_>,
header: Option<&message::Header<'_>>,
) -> fdo::Result<HashMap<String, OwnedValue>>;

Expand Down
6 changes: 4 additions & 2 deletions zbus/src/object_server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,9 @@ impl ObjectServer {
if name == ObjectManager::name() {
// Just added an object manager. Need to signal all managed objects under it.
let ctxt = SignalEmitter::new(&self.connection(), path)?;
let objects = node.get_managed_objects(self, &self.connection()).await?;
let objects = node
.get_managed_objects(self, &ctxt, &self.connection())
.await?;
for (path, owned_interfaces) in objects {
let interfaces = owned_interfaces
.iter()
Expand All @@ -166,7 +168,7 @@ impl ObjectServer {
let ctxt = SignalEmitter::new(&self.connection(), manager_path.clone())?;
let mut interfaces = HashMap::new();
let owned_props = node
.get_properties(self, &self.connection(), name.clone())
.get_properties(self, &self.connection(), &ctxt, name.clone())
.await?;
let props = owned_props
.iter()
Expand Down
7 changes: 5 additions & 2 deletions zbus/src/object_server/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use zvariant::{ObjectPath, OwnedObjectPath, OwnedValue};

use crate::{
fdo::{self, Introspectable, ManagedObjects, ObjectManager, Peer, Properties},
object_server::SignalEmitter,
Connection, ObjectServer,
};

Expand Down Expand Up @@ -214,6 +215,7 @@ impl Node {
pub(crate) async fn get_managed_objects(
&self,
object_server: &ObjectServer,
emitter: &SignalEmitter<'_>,
connection: &Connection,
) -> fdo::Result<ManagedObjects> {
let mut managed_objects = ManagedObjects::new();
Expand All @@ -230,7 +232,7 @@ impl Node {
&& *n != &ObjectManager::name()
}) {
let props = node
.get_properties(object_server, connection, iface_name.clone())
.get_properties(object_server, connection, emitter, iface_name.clone())
.await?;
interfaces.insert(iface_name.clone().into(), props);
}
Expand All @@ -245,14 +247,15 @@ impl Node {
&self,
object_server: &ObjectServer,
connection: &Connection,
emitter: &SignalEmitter<'_>,
interface_name: InterfaceName<'_>,
) -> fdo::Result<HashMap<String, OwnedValue>> {
self.interface_lock(interface_name)
.expect("Interface was added but not found")
.instance
.read()
.await
.get_all(object_server, connection, None)
.get_all(object_server, connection, emitter, None)
.await
}
}
5 changes: 3 additions & 2 deletions zbus/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,11 @@ impl MyIface {
#[zbus(header)] header: Option<Header<'_>>,
#[zbus(connection)] connection: &Connection,
#[zbus(object_server)] object_server: &ObjectServer,
#[zbus(signal_emitter)] emitter: SignalEmitter<'_>,
) -> bool {
debug!(
"`TestHeaderProp` getter called, header: {:?}, connection: {:?}, object_server: {:?}",
header, connection, object_server
"`TestHeaderProp` getter called, header: {:?}, connection: {:?}, object_server: {:?}, emitter: {:?}",
header, connection, object_server, emitter
);
header.is_some()
}
Expand Down
37 changes: 20 additions & 17 deletions zbus_macros/src/iface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ pub fn expand(args: Punctuated<Meta, Token![,]>, mut input: ItemImpl) -> syn::Re
property_name: &str,
object_server: &#zbus::ObjectServer,
connection: &#zbus::Connection,
signal_emitter: &#zbus::object_server::SignalEmitter<'_>,
header: Option<&#zbus::message::Header<'_>>,
) -> ::std::option::Option<#zbus::fdo::Result<#zbus::zvariant::OwnedValue>> {
match property_name {
Expand All @@ -891,6 +892,7 @@ pub fn expand(args: Punctuated<Meta, Token![,]>, mut input: ItemImpl) -> syn::Re
&self,
object_server: &#zbus::ObjectServer,
connection: &#zbus::Connection,
signal_emitter: &#zbus::object_server::SignalEmitter<'_>,
header: Option<&#zbus::message::Header<'_>>,
) -> #zbus::fdo::Result<::std::collections::HashMap<
::std::string::String,
Expand Down Expand Up @@ -1051,37 +1053,38 @@ fn get_args_from_inputs(

let signal_context_arg = &input.pat;

signal_emitter_arg_decl = Some(quote! {
let #signal_context_arg = match hdr.path() {
::std::option::Option::Some(p) => {
#zbus::object_server::SignalEmitter::new(connection, p).expect("Infallible conversion failed")
}
::std::option::Option::None => {
let err = #zbus::fdo::Error::UnknownObject("Path Required".into());
return connection.reply_dbus_error(&hdr, err).await;
}
};
});
signal_emitter_arg_decl = match method_type {
MethodType::Property(PropertyType::Getter) => {
Some(quote! { let #signal_context_arg = signal_emitter.clone(); })
}
_ => Some(quote! {
let #signal_context_arg = match hdr.path() {
::std::option::Option::Some(p) => {
#zbus::object_server::SignalEmitter::new(connection, p).expect("Infallible conversion failed")
}
::std::option::Option::None => {
let err = #zbus::fdo::Error::UnknownObject("Path Required".into());
return connection.reply_dbus_error(&hdr, err).await;
}
};
}),
};
} else {
args_names.push(pat_ident(input).unwrap());
tys.push(&input.ty);
}
}

let (hdr_init, msg_init, signal_emitter_arg_decl, args_decl) = match method_type {
MethodType::Property(PropertyType::Getter) => {
(quote! {}, quote! {}, quote! {}, quote! {})
}
let (hdr_init, msg_init, args_decl) = match method_type {
MethodType::Property(PropertyType::Getter) => (quote! {}, quote! {}, quote! {}),
MethodType::Property(PropertyType::Setter) => (
quote! { let hdr = header.as_ref().unwrap(); },
quote! {},
quote! { #signal_emitter_arg_decl },
quote! {},
),
_ => (
quote! { let hdr = message.header(); },
quote! { let msg_body = message.body(); },
quote! { #signal_emitter_arg_decl },
quote! {
let (#(#args_names),*): (#(#tys),*) =
match msg_body.deserialize() {
Expand Down
3 changes: 1 addition & 2 deletions zbus_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,7 @@ pub fn proxy(attr: TokenStream, item: TokenStream) -> TokenStream {
/// which will be set to `None` if the method is called for reasons other than to respond to an
/// external property access.
/// * `signal_emitter` - This marks the method argument to receive a [`SignalEmitter`] instance,
/// which is needed for emitting signals the easy way. This argument is not available for property
/// getters.
/// which is needed for emitting signals the easy way.
///
/// # Example
///
Expand Down

0 comments on commit 8e4a9df

Please sign in to comment.