-
-
Notifications
You must be signed in to change notification settings - Fork 133
Add some quality-of-life gdbus helpers #1558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
355f7db
9615413
cbd84ae
39b18f8
22688c1
7bb83b2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,8 @@ | ||
| use gio::prelude::*; | ||
| use std::sync::mpsc::{channel, Receiver, Sender}; | ||
| use gio::{prelude::*, IOErrorEnum}; | ||
| use std::{ | ||
| sync::mpsc::{channel, Receiver, Sender}, | ||
| time::Duration, | ||
| }; | ||
|
|
||
| const EXAMPLE_XML: &str = r#" | ||
| <node> | ||
|
|
@@ -8,10 +11,48 @@ const EXAMPLE_XML: &str = r#" | |
| <arg type='s' name='name' direction='in'/> | ||
| <arg type='s' name='greet' direction='out'/> | ||
| </method> | ||
| <method name='SlowHello'> | ||
| <arg type='s' name='name' direction='in'/> | ||
| <arg type='u' name='delay' direction='in'/> | ||
| <arg type='s' name='greet' direction='out'/> | ||
| </method> | ||
| </interface> | ||
| </node> | ||
| "#; | ||
|
|
||
| #[derive(Debug, glib::Variant)] | ||
| struct Hello { | ||
| name: String, | ||
| } | ||
|
|
||
| #[derive(Debug, glib::Variant)] | ||
| struct SlowHello { | ||
| name: String, | ||
| delay: u32, | ||
| } | ||
|
|
||
| #[derive(Debug)] | ||
| enum HelloMethod { | ||
| Hello(Hello), | ||
| SlowHello(SlowHello), | ||
| } | ||
|
|
||
| impl DBusMethodCall for HelloMethod { | ||
| fn parse_call( | ||
swsnr marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| _obj_path: &str, | ||
| _interface: &str, | ||
| method: &str, | ||
| params: glib::Variant, | ||
| ) -> Result<Self, glib::Error> { | ||
| match method { | ||
| "Hello" => Ok(params.get::<Hello>().map(Self::Hello)), | ||
| "SlowHello" => Ok(params.get::<SlowHello>().map(Self::SlowHello)), | ||
| _ => Err(glib::Error::new(IOErrorEnum::Failed, "No such method")), | ||
| } | ||
| .and_then(|p| p.ok_or_else(|| glib::Error::new(IOErrorEnum::Failed, "Invalid parameters"))) | ||
| } | ||
| } | ||
|
|
||
| fn on_startup(app: &gio::Application, tx: &Sender<gio::RegistrationId>) { | ||
| let connection = app.dbus_connection().expect("connection"); | ||
|
|
||
|
|
@@ -22,25 +63,25 @@ fn on_startup(app: &gio::Application, tx: &Sender<gio::RegistrationId>) { | |
|
|
||
| if let Ok(id) = connection | ||
| .register_object("/com/github/gtk_rs/examples/HelloWorld", &example) | ||
| .method_call(glib::clone!( | ||
| #[strong] | ||
| app, | ||
| move |_, _, _, _, method, params, invocation| { | ||
| match method { | ||
| "Hello" => { | ||
| if let Some((name,)) = <(String,)>::from_variant(¶ms) { | ||
| let greet = format!("Hello {name}!"); | ||
| println!("{greet}"); | ||
| invocation.return_value(Some(&(greet,).to_variant())); | ||
| } else { | ||
| invocation.return_error(gio::IOErrorEnum::Failed, "Invalid parameters"); | ||
| } | ||
| .typed_method_call::<HelloMethod>() | ||
| .invoke_and_return_future_local(|_, sender, call| { | ||
| println!("Method call from {sender}"); | ||
| async { | ||
| match call { | ||
| HelloMethod::Hello(Hello { name }) => { | ||
| let greet = format!("Hello {name}!"); | ||
| println!("{greet}"); | ||
| Ok(Some(greet.to_variant())) | ||
| } | ||
| HelloMethod::SlowHello(SlowHello { name, delay }) => { | ||
| glib::timeout_future(Duration::from_secs(delay as u64)).await; | ||
| let greet = format!("Hello {name} after {delay} seconds!"); | ||
| println!("{greet}"); | ||
| Ok(Some(greet.to_variant())) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably also figure out a way to make the return value more type safe
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type safety as in "the return value matches the signature of the Dbus interface"?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Maybe the structs in the enum need to implement a trait with an associated type for that, or so. I think that would all require a bit of reorganization though |
||
| } | ||
| _ => unreachable!(), | ||
| } | ||
| app.quit(); | ||
| } | ||
| )) | ||
| }) | ||
| .build() | ||
| { | ||
| println!("Registered object"); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.