diff --git a/rust/chg/src/lib.rs b/rust/chg/src/lib.rs --- a/rust/chg/src/lib.rs +++ b/rust/chg/src/lib.rs @@ -9,7 +9,7 @@ pub mod message; pub mod procutil; //mod runcommand; -//mod uihandler; +mod uihandler; //pub use clientext::ChgClientExt; -//pub use uihandler::{ChgUiHandler, SystemHandler}; +pub use uihandler::{ChgUiHandler, SystemHandler}; diff --git a/rust/chg/src/uihandler.rs b/rust/chg/src/uihandler.rs --- a/rust/chg/src/uihandler.rs +++ b/rust/chg/src/uihandler.rs @@ -3,8 +3,7 @@ // This software may be used and distributed according to the terms of the // GNU General Public License version 2 or any later version. -use futures::future::IntoFuture; -use futures::Future; +use async_trait::async_trait; use std::io; use std::os::unix::io::AsRawFd; use std::os::unix::process::ExitStatusExt; @@ -16,20 +15,19 @@ use crate::procutil; /// Callback to process shell command requests received from server. -pub trait SystemHandler: Sized { +#[async_trait] +pub trait SystemHandler { type PagerStdin: AsRawFd; - type SpawnPagerResult: IntoFuture; - type RunSystemResult: IntoFuture; /// Handles pager command request. /// /// Returns the pipe to be attached to the server if the pager is spawned. - fn spawn_pager(self, spec: CommandSpec) -> Self::SpawnPagerResult; + async fn spawn_pager(&mut self, spec: &CommandSpec) -> io::Result; /// Handles system command request. /// /// Returns command exit code (positive) or signal number (negative). - fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult; + async fn run_system(&mut self, spec: &CommandSpec) -> io::Result; } /// Default cHg implementation to process requests received from server. @@ -41,12 +39,11 @@ } } +#[async_trait] impl SystemHandler for ChgUiHandler { type PagerStdin = ChildStdin; - type SpawnPagerResult = io::Result<(Self, Self::PagerStdin)>; - type RunSystemResult = Box + Send>; - fn spawn_pager(self, spec: CommandSpec) -> Self::SpawnPagerResult { + async fn spawn_pager(&mut self, spec: &CommandSpec) -> io::Result { let mut pager = new_shell_command(&spec).stdin(Stdio::piped()).spawn()?; let pin = pager.stdin.take().unwrap(); procutil::set_blocking_fd(pin.as_raw_fd())?; @@ -54,23 +51,22 @@ // otherwise the server won't get SIGPIPE if it does not write // anything. (issue5278) // kill(peerpid, SIGPIPE); - tokio::spawn(pager.map(|_| ()).map_err(|_| ())); // just ignore errors - Ok((self, pin)) + tokio::spawn(async { pager.await }); // just ignore errors + Ok(pin) } - fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult { - let fut = new_shell_command(&spec) - .spawn() - .into_future() - .flatten() - .map(|status| { + async fn run_system(&mut self, spec: &CommandSpec) -> io::Result { + let status = new_shell_command(&spec).spawn()?.await?; + // TODO: unindent + { + { let code = status .code() .or_else(|| status.signal().map(|n| -n)) .expect("either exit code or signal should be set"); - (self, code) - }); - Box::new(fut) + Ok(code) + } + } } }