Skip to content

Commit

Permalink
🚧 Towards zvariant symbols directly under zbus dbus2#807
Browse files Browse the repository at this point in the history
WIP. Only hurdle is `zvariant_utils::def_attrs not supporting multiple attributes.
  • Loading branch information
zeenix committed Jun 1, 2024
1 parent f3f18a0 commit 25b9309
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 83 deletions.
2 changes: 1 addition & 1 deletion book/src/blocking.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Similar to `blocking::Connection`, you use `blocking::Proxy` type. Its construct
to use the blocking connection and proxy:

```rust,no_run
use zbus::{blocking::Connection, zvariant::ObjectPath, proxy, Result};
use zbus::{blocking::Connection, ObjectPath, proxy, Result};
#[proxy(
default_service = "org.freedesktop.GeoClue2",
Expand Down
24 changes: 11 additions & 13 deletions book/src/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ zbus `Connection` has a `call_method()` method, which you can use directly:
use std::collections::HashMap;
use std::error::Error;
use zbus::{zvariant::Value, Connection};
use zbus::{Value, Connection};
// Although we use `async-std` here, you can use any async runtime of choice.
#[async_std::main]
Expand Down Expand Up @@ -97,7 +97,7 @@ calls:
use std::collections::HashMap;
use std::error::Error;
use zbus::{zvariant::Value, proxy, Connection};
use zbus::{Value, proxy, Connection};
#[proxy(
default_service = "org.freedesktop.Notifications",
Expand Down Expand Up @@ -162,9 +162,7 @@ Let's look at this API in action, with an example where we monitor started syste
```rust,no_run
# // NOTE: When changing this, please also keep `zbus/examples/watch-systemd-jobs.rs` in sync.
use async_std::stream::StreamExt;
use zbus::Connection;
use zbus_macros::proxy;
use zvariant::OwnedObjectPath;
use zbus::{proxy, Connection, OwnedObjectPath};
# fn main() {
# async_io::block_on(watch_systemd_jobs()).expect("Error listening to signal");
Expand Down Expand Up @@ -208,7 +206,7 @@ Here is a more elaborate example, where we get our location from
[Geoclue](https://gitlab.freedesktop.org/geoclue/geoclue/-/blob/master/README.md):

```rust,no_run
use zbus::{zvariant::ObjectPath, proxy, Connection, Result};
use zbus::{ObjectPath, proxy, Connection, Result};
use futures_util::stream::StreamExt;
#[proxy(
Expand Down Expand Up @@ -379,12 +377,12 @@ Environment variables:
#### Trait-bounds for property values

If you use custom types for property values, you might get a compile error for missing
`TryFrom<zvariant::Value<'_>>` and/or `TryFrom<OwnedValue>` implementations. This is because
`TryFrom<zbus::Value<'_>>` and/or `TryFrom<OwnedValue>` implementations. This is because
properties are always sent as Variants on the bus, so you need to implement these conversions for
your custom types.

Not to worry though, the `zvariant` crate provides a [`Value`] and [`OwnedValue`] derive macro to
implement these conversions for you.
Not to worry though, we provides a [`Value`] and [`OwnedValue`] derive macro to implement these
conversions for you.

#### Watching for changes

Expand Down Expand Up @@ -552,7 +550,7 @@ trait Notifications {
arg_3: &str,
arg_4: &str,
arg_5: &[&str],
arg_6: std::collections::HashMap<&str, zvariant::Value<'_>>,
arg_6: std::collections::HashMap<&str, zbus::Value<'_>>,
arg_7: i32,
) -> zbus::Result<u32>;
Expand All @@ -574,7 +572,7 @@ For example, the generated `GetServerInformation` method can be improved to a ni

```rust,noplayground
# use serde::{Serialize, Deserialize};
# use zbus::{zvariant::Type, proxy};
# use zbus::{Type, proxy};
#
#[derive(Debug, Type, Serialize, Deserialize)]
pub struct ServerInformation {
Expand Down Expand Up @@ -616,7 +614,7 @@ There you have it, a Rust-friendly binding for your D-Bus service!
[`pkg-config`]: https://www.freedesktop.org/wiki/Software/pkg-config/
[cob]: blocking.html
[`Stream`]: https://docs.rs/futures/4/futures/stream/trait.Stream.html
[`Value`]: https://docs.rs/zvariant/4/zvariant/derive.Value.html
[`OwnedValue`]: https://docs.rs/zvariant/4/zvariant/derive.OwnedValue.html
[`Value`]: https://docs.rs/zbus/4.3.0/derive.Value.html
[`OwnedValue`]: https://docs.rs/4.3.0/derive.OwnedValue.html

[^busctl]: `busctl` is part of [`systemd`](https://www.freedesktop.org/wiki/Software/systemd/).
12 changes: 6 additions & 6 deletions book/src/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ Since the use of a dictionary, specifically one with strings as keys and variant
`a{sv}`) is very common in the D-Bus world and use of HashMaps isn't as convenient and type-safe as
a struct, you might find yourself wanting to use a struct as a dictionary.

`zvariant` provides convenient macros for making this possible: [`SerializeDict`] and
[`DeserializeDict`]. You'll also need to tell [`Type`] macro to treat the type as a dictionary using
the `signature` attribute. Here is a simple example:
We provide convenient macros for making this possible: [`SerializeDict`] and [`DeserializeDict`].\
You'll also need to tell [`Type`] macro to treat the type as a dictionary using the `signature`\
attribute. Here is a simple example:

```rust,noplayground
use zbus::{
proxy, interface, fdo::Result,
zvariant::{DeserializeDict, SerializeDict, Type},
DeserializeDict, SerializeDict, Type,
};
#[derive(DeserializeDict, SerializeDict, Type)]
// `Type` treats `dict` is an alias for `a{sv}`.
#[zvariant(signature = "dict")]
#[zbus(signature = "dict")]
pub struct Dictionary {
field1: u16,
#[zvariant(rename = "another-name")]
#[zbus(rename = "another-name")]
field2: i64,
optional_field: Option<String>,
}
Expand Down
3 changes: 1 addition & 2 deletions zbus/examples/watch-systemd-jobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
//! Run with command: `cargo run --example watch-systemd-jobs`

use async_std::stream::StreamExt;
use zbus::Connection;
use zbus::{Connection, OwnedObjectPath};
use zbus_macros::proxy;
use zvariant::OwnedObjectPath;

fn main() {
async_io::block_on(watch_systemd_jobs()).expect("Error listening to signal");
Expand Down
13 changes: 7 additions & 6 deletions zbus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ pub mod export {
}

pub use zbus_names as names;
pub use zvariant;
pub use zvariant::{
self, Array, DeserializeDict, Dict, DynamicTuple, DynamicType, Endian, Fd, NoneValue,
ObjectPath, Optional, OwnedFd, OwnedObjectPath, OwnedSignature, OwnedStructure, OwnedValue,
SerializeDict, SerializeValue, Signature, Str, Structure, StructureBuilder, Type, Value,
};

#[cfg(test)]
mod tests {
Expand Down Expand Up @@ -1042,13 +1046,10 @@ mod tests {
fn issue_466() {
#[crate::proxy(interface = "org.Some.Thing1", assume_defaults = true)]
trait MyGreeter {
fn foo(
&self,
arg: &(u32, zbus::zvariant::Value<'_>),
) -> zbus::Result<(u32, zbus::zvariant::OwnedValue)>;
fn foo(&self, arg: &(u32, zbus::Value<'_>)) -> zbus::Result<(u32, zbus::OwnedValue)>;

#[zbus(property)]
fn bar(&self) -> zbus::Result<(u32, zbus::zvariant::OwnedValue)>;
fn bar(&self) -> zbus::Result<(u32, zbus::OwnedValue)>;
}
}

Expand Down
12 changes: 6 additions & 6 deletions zbus/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl Sequence {
/// and hence use the API provided by [`Connection`], even when using the low-level API.
///
/// **Note**: The message owns the received FDs and will close them when dropped. You can
/// deserialize to [`zvariant::OwnedFd`] the body (that you get using [`Message::body`]) if you want
/// deserialize to [`zbus::OwnedFd`] the body (that you get using [`Message::body`]) if you want
/// to keep the FDs around after the containing message is dropped.
///
/// [`Connection`]: struct.Connection#method.call_method
Expand Down Expand Up @@ -245,19 +245,19 @@ impl Message {
/// # Example
///
/// ```
/// # use zbus::message::Message;
/// # use zbus::{message::Message, Value};
/// # (|| -> zbus::Result<()> {
/// let send_body = (7i32, (2i32, "foo"), vec!["bar"]);
/// let message = Message::method("/", "ping")?
/// .destination("zbus.test")?
/// .interface("zbus.test")?
/// .build(&send_body)?;
/// let body = message.body();
/// let body: zbus::zvariant::Structure = body.deserialize()?;
/// let body: zbus::Structure = body.deserialize()?;
/// let fields = body.fields();
/// assert!(matches!(fields[0], zvariant::Value::I32(7)));
/// assert!(matches!(fields[1], zvariant::Value::Structure(_)));
/// assert!(matches!(fields[2], zvariant::Value::Array(_)));
/// assert!(matches!(fields[0], Value::I32(7)));
/// assert!(matches!(fields[1], Value::Structure(_)));
/// assert!(matches!(fields[2], Value::Array(_)));
///
/// let reply_body = Message::method_reply(&message)?.build(&body)?.body();
/// let reply_value : (i32, (i32, &str), Vec<String>) = reply_body.deserialize()?;
Expand Down
32 changes: 16 additions & 16 deletions zbus_macros/src/iface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,8 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
// * For all other arg types, we convert the passed value to `OwnedValue` first
// and then pass it as `Value` (so `TryFrom<OwnedValue>` is required).
let value_to_owned = quote! {
match ::zbus::zvariant::Value::try_to_owned(value) {
::std::result::Result::Ok(val) => ::zbus::zvariant::Value::from(val),
match ::zbus::Value::try_to_owned(value) {
::std::result::Result::Ok(val) => ::zbus::Value::from(val),
::std::result::Result::Err(e) => {
return ::std::result::Result::Err(
::std::convert::Into::into(#zbus::Error::Variant(::std::convert::Into::into(e)))
Expand All @@ -516,7 +516,7 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
.args
.first()
.filter(|arg| matches!(arg, GenericArgument::Lifetime(_)))
.map(|_| quote!(match ::zbus::zvariant::Value::try_clone(value) {
.map(|_| quote!(match ::zbus::Value::try_clone(value) {
::std::result::Result::Ok(val) => val,
::std::result::Result::Err(e) => {
return ::std::result::Result::Err(
Expand Down Expand Up @@ -601,8 +601,8 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
p.ty = Some(get_property_type(output)?);
p.read = true;
let value_convert = quote!(
<#zbus::zvariant::OwnedValue as ::std::convert::TryFrom<_>>::try_from(
<#zbus::zvariant::Value as ::std::convert::From<_>>::from(
<#zbus::OwnedValue as ::std::convert::TryFrom<_>>::try_from(
<#zbus::Value as ::std::convert::From<_>>::from(
value,
),
)
Expand All @@ -629,8 +629,8 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
quote!(if let Ok(prop) = self.#ident()#method_await {
props.insert(
::std::string::ToString::to_string(#member_name),
<#zbus::zvariant::OwnedValue as ::std::convert::TryFrom<_>>::try_from(
<#zbus::zvariant::Value as ::std::convert::From<_>>::from(
<#zbus::OwnedValue as ::std::convert::TryFrom<_>>::try_from(
<#zbus::Value as ::std::convert::From<_>>::from(
prop,
),
)
Expand All @@ -640,8 +640,8 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
} else {
quote!(props.insert(
::std::string::ToString::to_string(#member_name),
<#zbus::zvariant::OwnedValue as ::std::convert::TryFrom<_>>::try_from(
<#zbus::zvariant::Value as ::std::convert::From<_>>::from(
<#zbus::OwnedValue as ::std::convert::TryFrom<_>>::try_from(
<#zbus::Value as ::std::convert::From<_>>::from(
self.#ident()#method_await,
),
)
Expand All @@ -663,7 +663,7 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
signal_context: &#zbus::object_server::SignalContext<'_>,
) -> #zbus::Result<()> {
let mut changed = ::std::collections::HashMap::new();
let value = <#zbus::zvariant::Value as ::std::convert::From<_>>::from(#prop_value_handled);
let value = <#zbus::Value as ::std::convert::From<_>>::from(#prop_value_handled);
changed.insert(#member_name, &value);
#zbus::fdo::Properties::properties_changed(
signal_context,
Expand Down Expand Up @@ -761,7 +761,7 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
async fn get(
&self,
property_name: &str,
) -> ::std::option::Option<#zbus::fdo::Result<#zbus::zvariant::OwnedValue>> {
) -> ::std::option::Option<#zbus::fdo::Result<#zbus::OwnedValue>> {
match property_name {
#get_dispatch
_ => ::std::option::Option::None,
Expand All @@ -772,11 +772,11 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
&self,
) -> #zbus::fdo::Result<::std::collections::HashMap<
::std::string::String,
#zbus::zvariant::OwnedValue,
#zbus::OwnedValue,
>> {
let mut props: ::std::collections::HashMap<
::std::string::String,
#zbus::zvariant::OwnedValue,
#zbus::OwnedValue,
> = ::std::collections::HashMap::new();
#get_all
Ok(props)
Expand All @@ -785,7 +785,7 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
fn set<'call>(
&'call self,
property_name: &'call str,
value: &'call #zbus::zvariant::Value<'_>,
value: &'call #zbus::Value<'_>,
signal_context: &'call #zbus::object_server::SignalContext<'_>,
) -> #zbus::object_server::DispatchResult<'call> {
match property_name {
Expand All @@ -797,7 +797,7 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
async fn set_mut(
&mut self,
property_name: &str,
value: &#zbus::zvariant::Value<'_>,
value: &#zbus::Value<'_>,
signal_context: &#zbus::object_server::SignalContext<'_>,
) -> ::std::option::Option<#zbus::fdo::Result<()>> {
match property_name {
Expand Down Expand Up @@ -841,7 +841,7 @@ pub fn expand<T: AttrParse + Into<TraitAttrs>, M: AttrParse + Into<MethodAttrs>>
indent = level
).unwrap();
{
use #zbus::zvariant::Type;
use #zbus::Type;

let level = level + 2;
#introspect
Expand Down
2 changes: 1 addition & 1 deletion zbus_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ mod utils;
/// ```no_run
/// # use std::error::Error;
/// use zbus_macros::proxy;
/// use zbus::{blocking::Connection, Result, fdo, zvariant::Value};
/// use zbus::{blocking::Connection, Result, fdo, Value};
/// use futures_util::stream::StreamExt;
/// use async_io::block_on;
///
Expand Down
22 changes: 11 additions & 11 deletions zbus_macros/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ pub fn create_proxy<M: AttrParse + Into<MethodAttrs>>(
where
D: ::std::convert::TryInto<#zbus::names::BusName<'static>>,
D::Error: ::std::convert::Into<#zbus::Error>,
P: ::std::convert::TryInto<#zbus::zvariant::ObjectPath<'static>>,
P: ::std::convert::TryInto<#zbus::ObjectPath<'static>>,
P::Error: ::std::convert::Into<#zbus::Error>,
{
let obj_path = path.try_into().map_err(::std::convert::Into::into)?;
Expand Down Expand Up @@ -389,7 +389,7 @@ pub fn create_proxy<M: AttrParse + Into<MethodAttrs>>(
/// Creates a new proxy with the given path, and the default destination.
pub #usage fn new<P>(conn: &#connection, path: P) -> #zbus::Result<#proxy_name<'p>>
where
P: ::std::convert::TryInto<#zbus::zvariant::ObjectPath<'static>>,
P: ::std::convert::TryInto<#zbus::ObjectPath<'static>>,
P::Error: ::std::convert::Into<#zbus::Error>,
{
let obj_path = path.try_into().map_err(::std::convert::Into::into)?;
Expand Down Expand Up @@ -493,9 +493,9 @@ pub fn create_proxy<M: AttrParse + Into<MethodAttrs>>(
}
}

impl<'p> #zbus::zvariant::Type for #proxy_name<'p> {
fn signature() -> #zbus::zvariant::Signature<'static> {
#zbus::zvariant::OwnedObjectPath::signature()
impl<'p> #zbus::Type for #proxy_name<'p> {
fn signature() -> #zbus::Signature<'static> {
#zbus::OwnedObjectPath::signature()
}
}

Expand Down Expand Up @@ -640,7 +640,7 @@ fn gen_proxy_method_call<M: AttrParse + Into<MethodAttrs>>(
parse_quote!(#zbus::export::serde::de::DeserializeOwned)
};
where_clause.predicates.push(parse_quote!(
#param: #serde_bound + #zbus::zvariant::Type
#param: #serde_bound + #zbus::Type
));
}
let (_, ty_generics, where_clause) = generics.split_for_impl();
Expand All @@ -655,10 +655,10 @@ fn gen_proxy_method_call<M: AttrParse + Into<MethodAttrs>>(
Ok(quote! {
#(#other_attrs)*
pub #usage #signature {
let object_path: #zbus::zvariant::OwnedObjectPath =
let object_path: #zbus::OwnedObjectPath =
self.0.call(
#method_name,
&#zbus::zvariant::DynamicTuple((#(#args,)*)),
&#zbus::DynamicTuple((#(#args,)*)),
)
#wait?;
#proxy_path::builder(&self.0.connection())
Expand All @@ -673,11 +673,11 @@ fn gen_proxy_method_call<M: AttrParse + Into<MethodAttrs>>(
// the '()' from the signature that we add and not the actual intended ones.
let arg = &args[0];
quote! {
&#zbus::zvariant::DynamicTuple((#arg,))
&#zbus::DynamicTuple((#arg,))
}
} else {
quote! {
&#zbus::zvariant::DynamicTuple((#(#args),*))
&#zbus::DynamicTuple((#(#args),*))
}
};

Expand Down Expand Up @@ -911,7 +911,7 @@ fn gen_proxy_signal(
{
where_clause
.predicates
.push(parse_quote!(#param: #zbus::export::serde::de::Deserialize<'s> + #zbus::zvariant::Type + ::std::fmt::Debug));
.push(parse_quote!(#param: #zbus::export::serde::de::Deserialize<'s> + #zbus::Type + ::std::fmt::Debug));
}
generics.params.push(parse_quote!('s));
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
Expand Down
2 changes: 1 addition & 1 deletion zbus_macros/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn test_interface() {
#[interface(name = "org.freedesktop.zbus.Test", spawn = false)]
impl<T: 'static> Test<T>
where
T: serde::ser::Serialize + zbus::zvariant::Type + Send + Sync,
T: serde::ser::Serialize + zbus::Type + Send + Sync,
{
/// Testing `no_arg` documentation is reflected in XML.
fn no_arg(&self) {
Expand Down
Loading

0 comments on commit 25b9309

Please sign in to comment.