##// END OF EJS Templates
rust-chg: reimplement ChgClientExt as ChgClient wrapper...
Yuya Nishihara -
r45236:d6f70692 default
parent child Browse files
Show More
@@ -5,55 +5,99 b''
5
5
6 //! cHg extensions to command server client.
6 //! cHg extensions to command server client.
7
7
8 use bytes::{BufMut, Bytes, BytesMut};
8 use bytes::{BufMut, BytesMut};
9 use std::ffi::OsStr;
9 use std::ffi::OsStr;
10 use std::io;
10 use std::io;
11 use std::mem;
11 use std::mem;
12 use std::os::unix::ffi::OsStrExt;
12 use std::os::unix::ffi::OsStrExt;
13 use std::os::unix::io::AsRawFd;
13 use std::os::unix::io::AsRawFd;
14 use std::path::Path;
14 use std::path::Path;
15 use tokio_hglib::protocol::{OneShotQuery, OneShotRequest};
15 use tokio_hglib::UnixClient;
16 use tokio_hglib::{Client, Connection};
17
16
18 use crate::attachio::AttachIo;
17 use crate::attachio;
19 use crate::message::{self, Instruction};
18 use crate::message::{self, Instruction, ServerSpec};
20 use crate::runcommand::ChgRunCommand;
19 use crate::runcommand;
21 use crate::uihandler::SystemHandler;
20 use crate::uihandler::SystemHandler;
22
21
23 pub trait ChgClientExt<C>
22 /// Command-server client that also supports cHg extensions.
24 where
23 pub struct ChgClient {
25 C: Connection + AsRawFd,
24 client: UnixClient,
26 {
25 }
26
27 impl ChgClient {
28 /// Connects to a command server listening at the specified socket path.
29 pub async fn connect(path: impl AsRef<Path>) -> io::Result<Self> {
30 let client = UnixClient::connect(path).await?;
31 Ok(ChgClient { client })
32 }
33
34 /// Server capabilities, encoding, etc.
35 pub fn server_spec(&self) -> &ServerSpec {
36 self.client.server_spec()
37 }
38
27 /// Attaches the client file descriptors to the server.
39 /// Attaches the client file descriptors to the server.
28 fn attach_io<I, O, E>(self, stdin: I, stdout: O, stderr: E) -> AttachIo<C, I, O, E>
40 pub async fn attach_io(
29 where
41 &mut self,
30 I: AsRawFd,
42 stdin: &impl AsRawFd,
31 O: AsRawFd,
43 stdout: &impl AsRawFd,
32 E: AsRawFd;
44 stderr: &impl AsRawFd,
45 ) -> io::Result<()> {
46 attachio::attach_io(self.client.borrow_protocol_mut(), stdin, stdout, stderr).await
47 }
33
48
34 /// Changes the working directory of the server.
49 /// Changes the working directory of the server.
35 fn set_current_dir(self, dir: impl AsRef<Path>) -> OneShotRequest<C>;
50 pub async fn set_current_dir(&mut self, dir: impl AsRef<Path>) -> io::Result<()> {
51 let dir_bytes = dir.as_ref().as_os_str().as_bytes().to_owned();
52 self.client
53 .borrow_protocol_mut()
54 .send_command_with_args("chdir", dir_bytes)
55 .await
56 }
36
57
37 /// Updates the environment variables of the server.
58 /// Updates the environment variables of the server.
38 fn set_env_vars_os(
59 pub async fn set_env_vars_os(
39 self,
60 &mut self,
40 vars: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>,
61 vars: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>,
41 ) -> OneShotRequest<C>;
62 ) -> io::Result<()> {
63 self.client
64 .borrow_protocol_mut()
65 .send_command_with_args("setenv", message::pack_env_vars_os(vars))
66 .await
67 }
42
68
43 /// Changes the process title of the server.
69 /// Changes the process title of the server.
44 fn set_process_name(self, name: impl AsRef<OsStr>) -> OneShotRequest<C>;
70 pub async fn set_process_name(&mut self, name: impl AsRef<OsStr>) -> io::Result<()> {
71 let name_bytes = name.as_ref().as_bytes().to_owned();
72 self.client
73 .borrow_protocol_mut()
74 .send_command_with_args("setprocname", name_bytes)
75 .await
76 }
45
77
46 /// Changes the umask of the server process.
78 /// Changes the umask of the server process.
47 fn set_umask(self, mask: u32) -> OneShotRequest<C>;
79 pub async fn set_umask(&mut self, mask: u32) -> io::Result<()> {
80 let mut mask_bytes = BytesMut::with_capacity(mem::size_of_val(&mask));
81 mask_bytes.put_u32(mask);
82 self.client
83 .borrow_protocol_mut()
84 .send_command_with_args("setumask2", mask_bytes)
85 .await
86 }
48
87
49 /// Runs the specified Mercurial command with cHg extension.
88 /// Runs the specified Mercurial command with cHg extension.
50 fn run_command_chg<H>(
89 pub async fn run_command_chg(
51 self,
90 &mut self,
52 handler: H,
91 handler: &mut impl SystemHandler,
53 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
92 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
54 ) -> ChgRunCommand<C, H>
93 ) -> io::Result<i32> {
55 where
94 runcommand::run_command(
56 H: SystemHandler;
95 self.client.borrow_protocol_mut(),
96 handler,
97 message::pack_args_os(args),
98 )
99 .await
100 }
57
101
58 /// Validates if the server can run Mercurial commands with the expected
102 /// Validates if the server can run Mercurial commands with the expected
59 /// configuration.
103 /// configuration.
@@ -63,66 +107,15 b' where'
63 ///
107 ///
64 /// Client-side environment must be sent prior to this request, by
108 /// Client-side environment must be sent prior to this request, by
65 /// `set_current_dir()` and `set_env_vars_os()`.
109 /// `set_current_dir()` and `set_env_vars_os()`.
66 fn validate(
110 pub async fn validate(
67 self,
111 &mut self,
68 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
112 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
69 ) -> OneShotQuery<C, fn(Bytes) -> io::Result<Vec<Instruction>>>;
113 ) -> io::Result<Vec<Instruction>> {
70 }
114 let data = self
71
115 .client
72 impl<C> ChgClientExt<C> for Client<C>
116 .borrow_protocol_mut()
73 where
117 .query_with_args("validate", message::pack_args_os(args))
74 C: Connection + AsRawFd,
118 .await?;
75 {
119 message::parse_instructions(data)
76 fn attach_io<I, O, E>(self, stdin: I, stdout: O, stderr: E) -> AttachIo<C, I, O, E>
77 where
78 I: AsRawFd,
79 O: AsRawFd,
80 E: AsRawFd,
81 {
82 AttachIo::with_client(self, stdin, stdout, Some(stderr))
83 }
84
85 fn set_current_dir(self, dir: impl AsRef<Path>) -> OneShotRequest<C> {
86 OneShotRequest::start_with_args(self, b"chdir", dir.as_ref().as_os_str().as_bytes())
87 }
88
89 fn set_env_vars_os(
90 self,
91 vars: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>,
92 ) -> OneShotRequest<C> {
93 OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars))
94 }
95
96 fn set_process_name(self, name: impl AsRef<OsStr>) -> OneShotRequest<C> {
97 OneShotRequest::start_with_args(self, b"setprocname", name.as_ref().as_bytes())
98 }
99
100 fn set_umask(self, mask: u32) -> OneShotRequest<C> {
101 let mut args = BytesMut::with_capacity(mem::size_of_val(&mask));
102 args.put_u32(mask);
103 OneShotRequest::start_with_args(self, b"setumask2", args)
104 }
105
106 fn run_command_chg<H>(
107 self,
108 handler: H,
109 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
110 ) -> ChgRunCommand<C, H>
111 where
112 H: SystemHandler,
113 {
114 ChgRunCommand::with_client(self, handler, message::pack_args_os(args))
115 }
116
117 fn validate(
118 self,
119 args: impl IntoIterator<Item = impl AsRef<OsStr>>,
120 ) -> OneShotQuery<C, fn(Bytes) -> io::Result<Vec<Instruction>>> {
121 OneShotQuery::start_with_args(
122 self,
123 b"validate",
124 message::pack_args_os(args),
125 message::parse_instructions,
126 )
127 }
120 }
128 }
121 }
@@ -4,12 +4,12 b''
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 mod attachio;
6 mod attachio;
7 //mod clientext;
7 mod clientext;
8 //pub mod locator;
8 //pub mod locator;
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::ChgClient;
15 pub use uihandler::{ChgUiHandler, SystemHandler};
15 pub use uihandler::{ChgUiHandler, SystemHandler};
General Comments 0
You need to be logged in to leave comments. Login now