##// END OF EJS Templates
rust-chg: reimplement uihandler by using async-trait and tokio-0.2...
Yuya Nishihara -
r45234:c794d0da default
parent child Browse files
Show More
@@ -9,7 +9,7 b' mod attachio;'
9 pub mod message;
9 pub mod message;
10 pub mod procutil;
10 pub mod procutil;
11 //mod runcommand;
11 //mod runcommand;
12 //mod uihandler;
12 mod uihandler;
13
13
14 //pub use clientext::ChgClientExt;
14 //pub use clientext::ChgClientExt;
15 //pub use uihandler::{ChgUiHandler, SystemHandler};
15 pub use uihandler::{ChgUiHandler, SystemHandler};
@@ -3,8 +3,7 b''
3 // This software may be used and distributed according to the terms of the
3 // This software may be used and distributed according to the terms of the
4 // GNU General Public License version 2 or any later version.
4 // GNU General Public License version 2 or any later version.
5
5
6 use futures::future::IntoFuture;
6 use async_trait::async_trait;
7 use futures::Future;
8 use std::io;
7 use std::io;
9 use std::os::unix::io::AsRawFd;
8 use std::os::unix::io::AsRawFd;
10 use std::os::unix::process::ExitStatusExt;
9 use std::os::unix::process::ExitStatusExt;
@@ -16,20 +15,19 b' use crate::message::CommandSpec;'
16 use crate::procutil;
15 use crate::procutil;
17
16
18 /// Callback to process shell command requests received from server.
17 /// Callback to process shell command requests received from server.
19 pub trait SystemHandler: Sized {
18 #[async_trait]
19 pub trait SystemHandler {
20 type PagerStdin: AsRawFd;
20 type PagerStdin: AsRawFd;
21 type SpawnPagerResult: IntoFuture<Item = (Self, Self::PagerStdin), Error = io::Error>;
22 type RunSystemResult: IntoFuture<Item = (Self, i32), Error = io::Error>;
23
21
24 /// Handles pager command request.
22 /// Handles pager command request.
25 ///
23 ///
26 /// Returns the pipe to be attached to the server if the pager is spawned.
24 /// Returns the pipe to be attached to the server if the pager is spawned.
27 fn spawn_pager(self, spec: CommandSpec) -> Self::SpawnPagerResult;
25 async fn spawn_pager(&mut self, spec: &CommandSpec) -> io::Result<Self::PagerStdin>;
28
26
29 /// Handles system command request.
27 /// Handles system command request.
30 ///
28 ///
31 /// Returns command exit code (positive) or signal number (negative).
29 /// Returns command exit code (positive) or signal number (negative).
32 fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult;
30 async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32>;
33 }
31 }
34
32
35 /// Default cHg implementation to process requests received from server.
33 /// Default cHg implementation to process requests received from server.
@@ -41,12 +39,11 b' impl ChgUiHandler {'
41 }
39 }
42 }
40 }
43
41
42 #[async_trait]
44 impl SystemHandler for ChgUiHandler {
43 impl SystemHandler for ChgUiHandler {
45 type PagerStdin = ChildStdin;
44 type PagerStdin = ChildStdin;
46 type SpawnPagerResult = io::Result<(Self, Self::PagerStdin)>;
47 type RunSystemResult = Box<dyn Future<Item = (Self, i32), Error = io::Error> + Send>;
48
45
49 fn spawn_pager(self, spec: CommandSpec) -> Self::SpawnPagerResult {
46 async fn spawn_pager(&mut self, spec: &CommandSpec) -> io::Result<Self::PagerStdin> {
50 let mut pager = new_shell_command(&spec).stdin(Stdio::piped()).spawn()?;
47 let mut pager = new_shell_command(&spec).stdin(Stdio::piped()).spawn()?;
51 let pin = pager.stdin.take().unwrap();
48 let pin = pager.stdin.take().unwrap();
52 procutil::set_blocking_fd(pin.as_raw_fd())?;
49 procutil::set_blocking_fd(pin.as_raw_fd())?;
@@ -54,23 +51,22 b' impl SystemHandler for ChgUiHandler {'
54 // otherwise the server won't get SIGPIPE if it does not write
51 // otherwise the server won't get SIGPIPE if it does not write
55 // anything. (issue5278)
52 // anything. (issue5278)
56 // kill(peerpid, SIGPIPE);
53 // kill(peerpid, SIGPIPE);
57 tokio::spawn(pager.map(|_| ()).map_err(|_| ())); // just ignore errors
54 tokio::spawn(async { pager.await }); // just ignore errors
58 Ok((self, pin))
55 Ok(pin)
59 }
56 }
60
57
61 fn run_system(self, spec: CommandSpec) -> Self::RunSystemResult {
58 async fn run_system(&mut self, spec: &CommandSpec) -> io::Result<i32> {
62 let fut = new_shell_command(&spec)
59 let status = new_shell_command(&spec).spawn()?.await?;
63 .spawn()
60 // TODO: unindent
64 .into_future()
61 {
65 .flatten()
62 {
66 .map(|status| {
67 let code = status
63 let code = status
68 .code()
64 .code()
69 .or_else(|| status.signal().map(|n| -n))
65 .or_else(|| status.signal().map(|n| -n))
70 .expect("either exit code or signal should be set");
66 .expect("either exit code or signal should be set");
71 (self, code)
67 Ok(code)
72 });
68 }
73 Box::new(fut)
69 }
74 }
70 }
75 }
71 }
76
72
General Comments 0
You need to be logged in to leave comments. Login now