Skip to content

Commit

Permalink
Demo async call handling for gdbus
Browse files Browse the repository at this point in the history
  • Loading branch information
swsnr committed Nov 1, 2024
1 parent cbd84ae commit 39b18f8
Showing 1 changed file with 31 additions and 12 deletions.
43 changes: 31 additions & 12 deletions examples/gio_dbus_register_object/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use gio::{prelude::*, IOErrorEnum};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::{
sync::mpsc::{channel, Receiver, Sender},
time::Duration,
};

const EXAMPLE_XML: &str = r#"
<node>
Expand All @@ -8,6 +11,11 @@ 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>
"#;
Expand All @@ -17,15 +25,23 @@ struct Hello {
name: String,
}

#[derive(Debug, glib::Variant)]
struct SlowHello {
name: String,
delay: u32,
}

#[derive(Debug)]
enum Call {
Hello(Hello),
SlowHello(SlowHello),
}

impl Call {
pub fn parse(method: &str, parameters: glib::Variant) -> Result<Call, glib::Error> {
match method {
"Hello" => Ok(parameters.get::<Hello>().map(Call::Hello)),
"SlowHello" => Ok(parameters.get::<SlowHello>().map(Call::SlowHello)),
_ => Err(glib::Error::new(IOErrorEnum::Failed, "No such method")),
}
.and_then(|p| p.ok_or_else(|| glib::Error::new(IOErrorEnum::Failed, "Invalid parameters")))
Expand All @@ -42,21 +58,24 @@ 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| {
let result = Call::parse(method, params).map(|call| match call {
.method_call(move |_, _, _, _, method, params, invocation| {
let call = Call::parse(method, params);
invocation.return_future_local(async move {
match call? {
Call::Hello(Hello { name }) => {
let greet = format!("Hello {name}!");
println!("{greet}");
Some(greet.to_variant())
Ok(Some(greet.to_variant()))
}
Call::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()))
}
});
invocation.return_result(result);
app.quit();
}
))
}
});
})
.build()
{
println!("Registered object");
Expand Down

0 comments on commit 39b18f8

Please sign in to comment.