gio/
subprocess.rs

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}