##// END OF EJS Templates
dirstate-v2: Add support when Rust is not enabled...
dirstate-v2: Add support when Rust is not enabled This wires into `dirstatemap` the parser and serializer added in previous changesets. The memory representation is still the same, with a flat `dict` for `DirstateItem`s and another one for copy sources. Serialization always creates a new dirstate-v2 data file and does not support (when Rust is not enabled) appending to an existing one, since we don’t keep track of which tree nodes are new or modified. Instead the tree is reconstructed during serialization. Differential Revision: https://phab.mercurial-scm.org/D11520

File last commit:

r48990:38deb65d default
r49037:b4f83c9e default
Show More
ui.rs
132 lines | 3.8 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;
Pulkit Goyal
rhg: add ui.plain() and check it before showing relative paths in status...
r48990 use std::env;
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 }
Pulkit Goyal
rhg: add ui.plain() and check it before showing relative paths in status...
r48990
/// is plain mode active
///
/// Plain mode means that all configuration variables which affect
/// the behavior and output of Mercurial should be
/// ignored. Additionally, the output should be stable,
/// reproducible and suitable for use in scripts or applications.
///
/// The only way to trigger plain mode is by setting either the
/// `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
///
/// The return value can either be
/// - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
/// - False if feature is disabled by default and not included in HGPLAIN
/// - True otherwise
pub fn plain(&self) -> bool {
// TODO: add support for HGPLAINEXCEPT
env::var_os("HGPLAIN").is_some()
}
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)
}