KillingSpark / KillingSpark/rustbus
Make 'org.freedesktop.DBus.Properties' easy to implement for services
- 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