clientext.rs
133 lines
| 4.0 KiB
| application/rls-services+xml
|
RustLexer
Yuya Nishihara
|
r40013 | // Copyright 2018 Yuya Nishihara <yuya@tcha.org> | ||
// | ||||
// This software may be used and distributed according to the terms of the | ||||
// GNU General Public License version 2 or any later version. | ||||
//! cHg extensions to command server client. | ||||
Yuya Nishihara
|
r45236 | use bytes::{BufMut, BytesMut}; | ||
Yuya Nishihara
|
r40013 | use std::ffi::OsStr; | ||
Yuya Nishihara
|
r45171 | use std::io; | ||
Yuya Nishihara
|
r45174 | use std::mem; | ||
Yuya Nishihara
|
r40014 | use std::os::unix::ffi::OsStrExt; | ||
Yuya Nishihara
|
r40013 | use std::os::unix::io::AsRawFd; | ||
Yuya Nishihara
|
r40014 | use std::path::Path; | ||
Yuya Nishihara
|
r45236 | use tokio_hglib::UnixClient; | ||
Yuya Nishihara
|
r40013 | |||
Yuya Nishihara
|
r45236 | use crate::attachio; | ||
use crate::message::{self, Instruction, ServerSpec}; | ||||
use crate::runcommand; | ||||
Yuya Nishihara
|
r45180 | use crate::uihandler::SystemHandler; | ||
Yuya Nishihara
|
r40013 | |||
Yuya Nishihara
|
r45236 | /// Command-server client that also supports cHg extensions. | ||
pub struct ChgClient { | ||||
client: UnixClient, | ||||
} | ||||
impl ChgClient { | ||||
/// Connects to a command server listening at the specified socket path. | ||||
pub async fn connect(path: impl AsRef<Path>) -> io::Result<Self> { | ||||
let client = UnixClient::connect(path).await?; | ||||
Ok(ChgClient { client }) | ||||
} | ||||
/// Server capabilities, encoding, etc. | ||||
pub fn server_spec(&self) -> &ServerSpec { | ||||
self.client.server_spec() | ||||
} | ||||
Yuya Nishihara
|
r40013 | /// Attaches the client file descriptors to the server. | ||
Yuya Nishihara
|
r45236 | pub async fn attach_io( | ||
&mut self, | ||||
stdin: &impl AsRawFd, | ||||
stdout: &impl AsRawFd, | ||||
stderr: &impl AsRawFd, | ||||
) -> io::Result<()> { | ||||
Martin von Zweigbergk
|
r46195 | attachio::attach_io( | ||
self.client.borrow_protocol_mut(), | ||||
stdin, | ||||
stdout, | ||||
stderr, | ||||
) | ||||
.await | ||||
Yuya Nishihara
|
r45236 | } | ||
Yuya Nishihara
|
r40013 | |||
Yuya Nishihara
|
r40014 | /// Changes the working directory of the server. | ||
Martin von Zweigbergk
|
r46195 | pub async fn set_current_dir( | ||
&mut self, | ||||
dir: impl AsRef<Path>, | ||||
) -> io::Result<()> { | ||||
Yuya Nishihara
|
r45236 | let dir_bytes = dir.as_ref().as_os_str().as_bytes().to_owned(); | ||
self.client | ||||
.borrow_protocol_mut() | ||||
.send_command_with_args("chdir", dir_bytes) | ||||
.await | ||||
} | ||||
Yuya Nishihara
|
r40014 | |||
Yuya Nishihara
|
r45165 | /// Updates the environment variables of the server. | ||
Yuya Nishihara
|
r45236 | pub async fn set_env_vars_os( | ||
&mut self, | ||||
Yuya Nishihara
|
r45183 | vars: impl IntoIterator<Item = (impl AsRef<OsStr>, impl AsRef<OsStr>)>, | ||
Yuya Nishihara
|
r45236 | ) -> io::Result<()> { | ||
self.client | ||||
.borrow_protocol_mut() | ||||
.send_command_with_args("setenv", message::pack_env_vars_os(vars)) | ||||
.await | ||||
} | ||||
Yuya Nishihara
|
r45165 | |||
Yuya Nishihara
|
r45175 | /// Changes the process title of the server. | ||
Martin von Zweigbergk
|
r46195 | pub async fn set_process_name( | ||
&mut self, | ||||
name: impl AsRef<OsStr>, | ||||
) -> io::Result<()> { | ||||
Yuya Nishihara
|
r45236 | let name_bytes = name.as_ref().as_bytes().to_owned(); | ||
self.client | ||||
.borrow_protocol_mut() | ||||
.send_command_with_args("setprocname", name_bytes) | ||||
.await | ||||
} | ||||
Yuya Nishihara
|
r45175 | |||
Yuya Nishihara
|
r45174 | /// Changes the umask of the server process. | ||
Yuya Nishihara
|
r45236 | pub async fn set_umask(&mut self, mask: u32) -> io::Result<()> { | ||
let mut mask_bytes = BytesMut::with_capacity(mem::size_of_val(&mask)); | ||||
mask_bytes.put_u32(mask); | ||||
self.client | ||||
.borrow_protocol_mut() | ||||
.send_command_with_args("setumask2", mask_bytes) | ||||
.await | ||||
} | ||||
Yuya Nishihara
|
r45174 | |||
Yuya Nishihara
|
r40013 | /// Runs the specified Mercurial command with cHg extension. | ||
Yuya Nishihara
|
r45236 | pub async fn run_command_chg( | ||
&mut self, | ||||
handler: &mut impl SystemHandler, | ||||
Yuya Nishihara
|
r45183 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, | ||
Yuya Nishihara
|
r45236 | ) -> io::Result<i32> { | ||
runcommand::run_command( | ||||
self.client.borrow_protocol_mut(), | ||||
handler, | ||||
message::pack_args_os(args), | ||||
) | ||||
.await | ||||
} | ||||
Yuya Nishihara
|
r45171 | |||
/// Validates if the server can run Mercurial commands with the expected | ||||
/// configuration. | ||||
/// | ||||
/// The `args` should contain early command arguments such as `--config` | ||||
/// and `-R`. | ||||
/// | ||||
/// Client-side environment must be sent prior to this request, by | ||||
/// `set_current_dir()` and `set_env_vars_os()`. | ||||
Yuya Nishihara
|
r45236 | pub async fn validate( | ||
&mut self, | ||||
Yuya Nishihara
|
r45183 | args: impl IntoIterator<Item = impl AsRef<OsStr>>, | ||
Yuya Nishihara
|
r45236 | ) -> io::Result<Vec<Instruction>> { | ||
let data = self | ||||
.client | ||||
.borrow_protocol_mut() | ||||
.query_with_args("validate", message::pack_args_os(args)) | ||||
.await?; | ||||
message::parse_instructions(data) | ||||
Yuya Nishihara
|
r45171 | } | ||
Yuya Nishihara
|
r40013 | } | ||