rust/rhg/src/ui.rs
author Simon Sapin <simon.sapin@octobus.net>
Thu, 10 Feb 2022 12:52:25 +0100
changeset 48731 f591b377375f
parent 48730 1aaf11e35aec
child 48733 39c447e03dbc
permissions -rw-r--r--
rhg: Make Ui::new falliable, add Ui::new_infallible This allows propagating color configuration errors Differential Revision: https://phab.mercurial-scm.org/D12165
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45984
fada33872b5b rhg: use `format_bytes!` for error messages
Raphaël Gomès <rgomes@octobus.net>
parents: 45528
diff changeset
     1
use format_bytes::format_bytes;
48730
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48729
diff changeset
     2
use hg::config::Config;
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
     3
use hg::errors::HgError;
48729
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
     4
use hg::utils::files::get_bytes_from_os_string;
45528
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
     5
use std::borrow::Cow;
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
     6
use std::env;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     7
use std::io;
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
     8
use std::io::{ErrorKind, Write};
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
     9
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    10
#[derive(Debug)]
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    11
pub struct Ui {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    12
    stdout: std::io::Stdout,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    13
    stderr: std::io::Stderr,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    14
}
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    15
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    16
/// The kind of user interface error
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    17
pub enum UiError {
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    18
    /// The standard output stream cannot be written to
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    19
    StdoutError(io::Error),
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    20
    /// The standard error stream cannot be written to
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    21
    StderrError(io::Error),
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    22
}
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    23
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    24
/// The commandline user interface
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    25
impl Ui {
48731
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    26
    pub fn new(_config: &Config) -> Result<Self, HgError> {
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    27
        Ok(Ui {
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    28
            stdout: std::io::stdout(),
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    29
            stderr: std::io::stderr(),
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    30
        })
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    31
    }
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    32
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    33
    /// Default to no color if color configuration errors.
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    34
    ///
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    35
    /// Useful when we’re already handling another error.
f591b377375f rhg: Make Ui::new falliable, add Ui::new_infallible
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
    36
    pub fn new_infallible(_config: &Config) -> Self {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    37
        Ui {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    38
            stdout: std::io::stdout(),
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    39
            stderr: std::io::stderr(),
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    40
        }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    41
    }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    42
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    43
    /// Returns a buffered handle on stdout for faster batch printing
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    44
    /// operations.
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    45
    pub fn stdout_buffer(&self) -> StdoutBuffer<std::io::StdoutLock> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    46
        StdoutBuffer::new(self.stdout.lock())
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    47
    }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    48
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    49
    /// Write bytes to stdout
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    50
    pub fn write_stdout(&self, bytes: &[u8]) -> Result<(), UiError> {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    51
        let mut stdout = self.stdout.lock();
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    52
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
    53
        stdout.write_all(bytes).or_else(handle_stdout_error)?;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    54
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
    55
        stdout.flush().or_else(handle_stdout_error)
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    56
    }
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    57
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    58
    /// Write bytes to stderr
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    59
    pub fn write_stderr(&self, bytes: &[u8]) -> Result<(), UiError> {
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    60
        let mut stderr = self.stderr.lock();
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    61
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
    62
        stderr.write_all(bytes).or_else(handle_stderr_error)?;
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    63
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
    64
        stderr.flush().or_else(handle_stderr_error)
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    65
    }
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    66
48513
47f2a82ae3e4 rhg: Fall back to Python if verbose status is requested by config
Simon Sapin <simon.sapin@octobus.net>
parents: 48176
diff changeset
    67
    /// Return whether plain mode is active.
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    68
    ///
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    69
    /// Plain mode means that all configuration variables which affect
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    70
    /// the behavior and output of Mercurial should be
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    71
    /// ignored. Additionally, the output should be stable,
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    72
    /// reproducible and suitable for use in scripts or applications.
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    73
    ///
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    74
    /// The only way to trigger plain mode is by setting either the
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    75
    /// `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    76
    ///
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    77
    /// The return value can either be
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    78
    /// - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    79
    /// - False if feature is disabled by default and not included in HGPLAIN
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    80
    /// - True otherwise
48729
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    81
    pub fn plain(&self, feature: Option<&str>) -> bool {
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    82
        plain(feature)
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    83
    }
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    84
}
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    85
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    86
fn plain(opt_feature: Option<&str>) -> bool {
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    87
    if let Some(except) = env::var_os("HGPLAINEXCEPT") {
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    88
        opt_feature.map_or(true, |feature| {
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    89
            get_bytes_from_os_string(except)
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    90
                .split(|&byte| byte == b',')
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    91
                .all(|exception| exception != feature.as_bytes())
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    92
        })
99b1dfc06571 rhg: Add support for HGPLAINEXPECT
Simon Sapin <simon.sapin@octobus.net>
parents: 48513
diff changeset
    93
    } else {
48176
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    94
        env::var_os("HGPLAIN").is_some()
38deb65d4441 rhg: add ui.plain() and check it before showing relative paths in status
Pulkit Goyal <7895pulkit@gmail.com>
parents: 46591
diff changeset
    95
    }
45049
513b3ef277a3 rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
diff changeset
    96
}
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    97
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    98
/// A buffered stdout writer for faster batch printing operations.
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
    99
pub struct StdoutBuffer<W: Write> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   100
    buf: io::BufWriter<W>,
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   101
}
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   102
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   103
impl<W: Write> StdoutBuffer<W> {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   104
    pub fn new(writer: W) -> Self {
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   105
        let buf = io::BufWriter::new(writer);
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   106
        Self { buf }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   107
    }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   108
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   109
    /// Write bytes to stdout buffer
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   110
    pub fn write_all(&mut self, bytes: &[u8]) -> Result<(), UiError> {
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
   111
        self.buf.write_all(bytes).or_else(handle_stdout_error)
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   112
    }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   113
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   114
    /// Flush bytes to stdout
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   115
    pub fn flush(&mut self) -> Result<(), UiError> {
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
   116
        self.buf.flush().or_else(handle_stdout_error)
45362
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   117
    }
eb55274d3650 rhg: add buffered stdout writing possibility
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45049
diff changeset
   118
}
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   119
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   120
/// Sometimes writing to stdout is not possible, try writing to stderr to
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   121
/// signal that failure, otherwise just bail.
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   122
fn handle_stdout_error(error: io::Error) -> Result<(), UiError> {
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   123
    if let ErrorKind::BrokenPipe = error.kind() {
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   124
        // This makes `| head` work for example
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   125
        return Ok(());
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   126
    }
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   127
    let mut stderr = io::stderr();
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   128
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   129
    stderr
45984
fada33872b5b rhg: use `format_bytes!` for error messages
Raphaël Gomès <rgomes@octobus.net>
parents: 45528
diff changeset
   130
        .write_all(&format_bytes!(
fada33872b5b rhg: use `format_bytes!` for error messages
Raphaël Gomès <rgomes@octobus.net>
parents: 45528
diff changeset
   131
            b"abort: {}\n",
fada33872b5b rhg: use `format_bytes!` for error messages
Raphaël Gomès <rgomes@octobus.net>
parents: 45528
diff changeset
   132
            error.to_string().as_bytes()
fada33872b5b rhg: use `format_bytes!` for error messages
Raphaël Gomès <rgomes@octobus.net>
parents: 45528
diff changeset
   133
        ))
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
   134
        .map_err(UiError::StderrError)?;
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   135
45439
fbc373b7cbc3 rhg: fix `clippy` warnings
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45367
diff changeset
   136
    stderr.flush().map_err(UiError::StderrError)?;
45366
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   137
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   138
    Err(UiError::StdoutError(error))
10c36ead86f8 rhg: extract function handle_stdout_error
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45362
diff changeset
   139
}
45367
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   140
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   141
/// Sometimes writing to stderr is not possible.
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   142
fn handle_stderr_error(error: io::Error) -> Result<(), UiError> {
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   143
    // A broken pipe should not result in a error
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   144
    // like with `| head` for example
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   145
    if let ErrorKind::BrokenPipe = error.kind() {
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   146
        return Ok(());
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   147
    }
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   148
    Err(UiError::StdoutError(error))
53af26aa5951 rhg: handle broken pipe error for stderr
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45366
diff changeset
   149
}
45528
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   150
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   151
/// Encode rust strings according to the user system.
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   152
pub fn utf8_to_local(s: &str) -> Cow<[u8]> {
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   153
    // TODO encode for the user's system //
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   154
    let bytes = s.as_bytes();
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   155
    Cow::Borrowed(bytes)
66756b34c06e rhg: add a `DebugData` `Command` to prepare the `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents: 45440
diff changeset
   156
}