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