KillingSpark / KillingSpark/rustbus

Make 'org.freedesktop.DBus.Properties' easy to implement for services

Open
#47 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
65
Forks
14
PR merge metrics
No merged PRs in 30d

Description

Currently you would have to write that boilerplate code on your own. A proc-macro that derives the relevant getters and setters would be nice.

Something like this trait should be fulfilled afterwards:
```rust
trait DbusProperties {
fn properties_get(&self, name: &str, request: &MarshalledMessage) -> MarshalledMessage;
fn properties_set(&mut self, name: &str, request: &MarshalledMessage) -> MarshalledMessage;
fn properties_get_all(&self, request: &MarshalledMessage) -> MarshalledMessage;
}
```
The returned messages are just either normal responses or error responses that adhere to the [spec here](https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties).
```
org.freedesktop.DBus.Properties.Get (in STRING interface_name,
in STRING property_name,
out VARIANT value);
org.freedesktop.DBus.Properties.Set (in STRING interface_name,
in STRING property_name,
in VARIANT value);
org.freedesktop.DBus.Properties.GetAll (in STRING interface_name,
out DICT props);
```
Sending the `org.freedesktop.DBus.Properties.PropertiesChanged` signal should be added at a later time. This is tied more directly to how and by whom the connection is handled.

As an somewhat trivial example:
```rust
#[derive(DbusProperties)]
struct Contact {
#[dbus_prop_name(ContactID), dbus_prop_ro]
id: u64,
#[dbus_prop_name(LastName), dbus_prop_rw]
name: String,
#[dbus_prop_name(MobileNumber), dbus_prop_rw]
mobile_number: String,

field_that_wont_be_visible: SecretKey,
}
```

```rust
fn properties_set(&mut self, name: &str, request: &MarshalledMessage) -> MarshalledMessage {
match name {
"ContactID" => {/* return error message because that is RO */},
"LastName" => {/* return normal success message */},
"MobileNumber" => {/* return normal success message */},
other => {/* return error message that says $other is not known */}
}
}

fn properties_get(&mut self, name: &str, request: &MarshalledMessage) -> MarshalledMessage {
match name {
"ContactID" => {/* return success message with self.id*/},
"LastName" => {/* return success message with self.name */},
"MobileNumber" => {/* return success message with self.mobile_number */},
other => {/* return error message that says $other is not known */}
}
}
```

The default should probably be a read-only property just to be on the safe side. Stuff that is not tagged with any `dbus_prop_*` attributes should never be read or written in the generated code. If no name is given, the field name should be transformed into camel-case, to fit the dbus conventions. Everything tagged with a `dbus_property_*` has to be `Marshal + Unmarshal` for this macro to work properly.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the DbusProperties trait sketch, the #[derive(DbusProperties)] example, and the linked org.freedesktop.DBus.Properties specification. The work is complete when the macro handles the documented read-only, read-write, hidden, naming, type, and error-response behavior, while leaving PropertiesChanged for later.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.