1 #[cfg(feature = "futures")]
2 use futures::future;
3 use gio_sys;
4 use glib::translate::*;
5 use glib::GString;
6 use glib_sys;
7 use gobject_sys;
8 use libc::c_char;
9 use std::ptr;
10 use Cancellable;
11 use Error;
12 use Subprocess;
13 
14 impl Subprocess {
communicate_utf8_async<R: FnOnce(Result<(GString, GString), Error>) + Send + 'static>( &self, stdin_buf: Option<String>, cancellable: Option<&Cancellable>, callback: R, )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")]
communicate_utf8_async_future( &self, stdin_buf: Option<String>, ) -> Box<dyn future::Future<Output = Result<(GString, GString), Error>> + std::marker::Unpin>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 }
81