##// END OF EJS Templates
revlog-compression: use zstd by default (if available)...
revlog-compression: use zstd by default (if available) As see in changeset bb271ec2fbfb, zstd is 20% to 50% faster for reading and writing. Use take advantage of the new config behavior to try zstd by default, falling back to zlib is zstd is not available on that plateform. Differential Revision: https://phab.mercurial-scm.org/D10326

File last commit:

r47333:21d3b40b default
r47636:84a93fa7 default
Show More
ui.rs
112 lines | 3.0 KiB | application/rls-services+xml | RustLexer
Raphaël Gomès
rhg: use `format_bytes!` for error messages...
r46598 use format_bytes::format_bytes;
Antoine Cezar
rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand...
r46099 use std::borrow::Cow;
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 use std::io;
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 use std::io::{ErrorKind, Write};
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 #[derive(Debug)]
pub struct Ui {
stdout: std::io::Stdout,
stderr: std::io::Stderr,
}
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
/// The kind of user interface error
pub enum UiError {
/// The standard output stream cannot be written to
StdoutError(io::Error),
/// The standard error stream cannot be written to
StderrError(io::Error),
}
/// The commandline user interface
impl Ui {
pub fn new() -> Self {
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 Ui {
stdout: std::io::stdout(),
stderr: std::io::stderr(),
}
}
/// Returns a buffered handle on stdout for faster batch printing
/// operations.
pub fn stdout_buffer(&self) -> StdoutBuffer<std::io::StdoutLock> {
StdoutBuffer::new(self.stdout.lock())
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
/// Write bytes to stdout
pub fn write_stdout(&self, bytes: &[u8]) -> Result<(), UiError> {
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 let mut stdout = self.stdout.lock();
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 stdout.write_all(bytes).or_else(handle_stdout_error)?;
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 stdout.flush().or_else(handle_stdout_error)
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
/// Write bytes to stderr
pub fn write_stderr(&self, bytes: &[u8]) -> Result<(), UiError> {
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 let mut stderr = self.stderr.lock();
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 stderr.write_all(bytes).or_else(handle_stderr_error)?;
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 stderr.flush().or_else(handle_stderr_error)
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
}
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921
/// A buffered stdout writer for faster batch printing operations.
pub struct StdoutBuffer<W: Write> {
buf: io::BufWriter<W>,
}
impl<W: Write> StdoutBuffer<W> {
pub fn new(writer: W) -> Self {
let buf = io::BufWriter::new(writer);
Self { buf }
}
/// Write bytes to stdout buffer
pub fn write_all(&mut self, bytes: &[u8]) -> Result<(), UiError> {
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 self.buf.write_all(bytes).or_else(handle_stdout_error)
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 }
/// Flush bytes to stdout
pub fn flush(&mut self) -> Result<(), UiError> {
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 self.buf.flush().or_else(handle_stdout_error)
Antoine Cezar
rhg: add buffered stdout writing possibility...
r45921 }
}
Antoine Cezar
rhg: extract function handle_stdout_error...
r45925
/// Sometimes writing to stdout is not possible, try writing to stderr to
/// signal that failure, otherwise just bail.
fn handle_stdout_error(error: io::Error) -> Result<(), UiError> {
if let ErrorKind::BrokenPipe = error.kind() {
// This makes `| head` work for example
return Ok(());
}
let mut stderr = io::stderr();
stderr
Raphaël Gomès
rhg: use `format_bytes!` for error messages...
r46598 .write_all(&format_bytes!(
b"abort: {}\n",
error.to_string().as_bytes()
))
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 .map_err(UiError::StderrError)?;
Antoine Cezar
rhg: extract function handle_stdout_error...
r45925
Antoine Cezar
rhg: fix `clippy` warnings...
r46010 stderr.flush().map_err(UiError::StderrError)?;
Antoine Cezar
rhg: extract function handle_stdout_error...
r45925
Err(UiError::StdoutError(error))
}
Antoine Cezar
rhg: handle broken pipe error for stderr...
r45926
/// Sometimes writing to stderr is not possible.
fn handle_stderr_error(error: io::Error) -> Result<(), UiError> {
// A broken pipe should not result in a error
// like with `| head` for example
if let ErrorKind::BrokenPipe = error.kind() {
return Ok(());
}
Err(UiError::StdoutError(error))
}
Antoine Cezar
rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand...
r46099
/// Encode rust strings according to the user system.
pub fn utf8_to_local(s: &str) -> Cow<[u8]> {
// TODO encode for the user's system //
let bytes = s.as_bytes();
Cow::Borrowed(bytes)
}