1#[cfg(feature = "futures")]
2use futures::future;
3use gio_sys;
4use glib::translate::*;
5use glib::GString;
6use glib_sys;
7use gobject_sys;
8use libc::c_char;
9use std::ptr;
10use Cancellable;
11use Error;
12use Subprocess;
13
14impl Subprocess {
15 pub fn communicate_utf8_async<R: FnOnce(Result<(GString, GString), Error>) + Send + 'static>(
16 &self,
17 stdin_buf: Option<String>,
18 cancellable: Option<&Cancellable>,
19 callback: R,
20 ) {
21 let stdin_buf = stdin_buf.to_glib_full();
22 let cancellable = cancellable.to_glib_none();
23 let user_data: Box<(R, *mut c_char)> = Box::new((callback, stdin_buf));
24 unsafe extern "C" fn communicate_utf8_async_trampoline<
25 R: FnOnce(Result<(GString, GString), Error>) + Send + 'static,
26 >(
27 _source_object: *mut gobject_sys::GObject,
28 res: *mut gio_sys::GAsyncResult,
29 user_data: glib_sys::gpointer,
30 ) {
31 let mut error = ptr::null_mut();
32 let mut stdout_buf = ptr::null_mut();
33 let mut stderr_buf = ptr::null_mut();
34 let _ = gio_sys::g_subprocess_communicate_utf8_finish(
35 _source_object as *mut _,
36 res,
37 &mut stdout_buf,
38 &mut stderr_buf,
39 &mut error,
40 );
41 let result = if error.is_null() {
42 Ok((from_glib_full(stdout_buf), from_glib_full(stderr_buf)))
43 } else {
44 Err(from_glib_full(error))
45 };
46 let callback: Box<(R, *mut c_char)> = Box::from_raw(user_data as *mut _);
47 glib_sys::g_free(callback.1 as *mut _);
48 callback.0(result);
49 }
50 unsafe {
51 gio_sys::g_subprocess_communicate_utf8_async(
52 self.to_glib_none().0,
53 stdin_buf,
54 cancellable.0,
55 Some(communicate_utf8_async_trampoline::<R>),
56 Box::into_raw(user_data) as *mut _,
57 );
58 }
59 }
60
61 #[cfg(feature = "futures")]
62 pub fn communicate_utf8_async_future(
63 &self,
64 stdin_buf: Option<String>,
65 ) -> Box<dyn future::Future<Output = Result<(GString, GString), Error>> + std::marker::Unpin>
66 {
67 use fragile::Fragile;
68 use GioFuture;
69
70 GioFuture::new(self, move |obj, send| {
71 let cancellable = Cancellable::new();
72 let send = Fragile::new(send);
73 obj.communicate_utf8_async(stdin_buf, Some(&cancellable), move |res| {
74 let _ = send.into_inner().send(res);
75 });
76
77 cancellable
78 })
79 }
80}