@@ -353,8 +353,81 @@ iface.greeter_name_changed(iface_ref.signal_context()).await?;
353
353
# }
354
354
```
355
355
356
+ ## Proxy generation
357
+
358
+ ` interface ` macro can also generate the client-side proxy code for you. It utilizes the [ ` proxy ` ]
359
+ macro behind the scenes to achieve this. Here is how to use it:
360
+
361
+ ``` rust
362
+ use zbus :: interface;
363
+
364
+ struct Greeter {
365
+ name : String
366
+ }
367
+
368
+ #[interface(
369
+ name = " org.zbus.MyGreeter.WithProxy" ,
370
+ // Specifying the `proxy` attribute instructs `interface` to generate the
371
+ // client-side proxy. You can specify proxy-specific attributes
372
+ // (e.g `gen_blocking) here. All the attributes that are common between
373
+ // `proxy` and `interface` macros (e.g `name`) are automtically forwarded to
374
+ // the `proxy` macro.
375
+ proxy(
376
+ gen_blocking = false,
377
+ default_path = " /org/zbus/MyGreeter/WithProxy" ,
378
+ default_service = " org.zbus.MyGreeter.WithProxy" ,
379
+ ),
380
+ )]
381
+ impl Greeter {
382
+ #[zbus(property)]
383
+ async fn greeter_name (& self ) -> String {
384
+ self . name. clone ()
385
+ }
386
+
387
+ #[zbus(proxy(no_reply))]
388
+ async fn whatever (& self ) {
389
+ println! (" Whatever!" );
390
+ }
391
+ }
392
+
393
+ # #[tokio:: main]
394
+ # async fn main () -> zbus :: Result <()> {
395
+
396
+ let greeter = Greeter { name : " GreeterName" . to_string () };
397
+ let connection = zbus :: connection :: Builder :: session ()?
398
+ . name (" org.zbus.MyGreeter.WithProxy" )?
399
+ . serve_at (" /org/zbus/MyGreeter/WithProxy" , greeter )?
400
+ . build ()
401
+ . await ? ;
402
+ let proxy = GreeterProxy :: new (& connection ). await ? ;
403
+ assert_eq! (proxy . greeter_name (). await ? , " GreeterName" );
404
+ proxy . whatever (). await ? ;
405
+
406
+ # Ok (())
407
+ # }
408
+ ```
409
+
410
+ ### Known Limitations
411
+
412
+ While it's extremely useful to be able to generate the client-side proxy code directly from
413
+ ` interface ` as it allows you to avoid duplicating code, there are some limitations to be aware of:
414
+
415
+ * The trait bounds of the ` proxy ` macro methods' arguments and return value, now also apply to the
416
+ ` interface ` methods. For example, when only generating the server-side code, the method return
417
+ values need to implement ` serde::Serialize ` but when generating the client-side proxy code, the
418
+ method return values need to implement ` serde::DeserializeOwned ` as well.
419
+ * Reference types in return values of ` interface ` methods won't work. As you may have noticed,
420
+ unlike the previous examples the ` greeter_name ` method in the example above returns a ` String `
421
+ instead of a ` &str ` . This is because the methods in the ` proxy ` macro do not support reference
422
+ type to be returned from its methods.
423
+ * Methods returning [ ` object_server::ResponseDispatchNotifier ` ] wrapper type will do the same for
424
+ proxy as well.
425
+ * Only ` interface ` macro supports this feature, while the deprecated ` dbus_interface ` macro does
426
+ not. Still haven't switched to ` interface ` and want to use this feature? Time to switch!
427
+
356
428
[ D-Bus concepts ] : concepts.html#bus-name--service-name
357
429
[ didoc ] : https://docs.rs/zbus/4/zbus/attr.interface.html
358
430
[ `zbus::DBusError` ] :https://docs.rs/zbus/4/zbus/trait.DBusError.html
359
431
[ `zbus::fdo::Error` ] : https://docs.rs/zbus/4/zbus/fdo/enum.Error.html
360
432
[ `zbus::fdo::Error::UnknownProperty` ] : https://docs.rs/zbus/4/zbus/fdo/enum.Error.html#variant.UnknownProperty
433
+ [ `proxy` ] : https://docs.rs/zbus/4/zbus/attr.proxy.html
0 commit comments