view rust/rhg/src/commands/root.rs @ 45378:452ece5654c5

hg-core: remove the `Operation` trait There is no way to currently define a trait which can both return references to `self` and to passed data, which is what we would need. Generic Associated Types may fix this and allow us to have a unified interface. See: rust #44265 Differential Revision: https://phab.mercurial-scm.org/D8862
author Antoine Cezar <antoine.cezar@octobus.net>
date Wed, 29 Jul 2020 10:08:09 +0200
parents 513b3ef277a3
children 227281e76c22
line wrap: on
line source

use crate::commands::Command;
use crate::error::{CommandError, CommandErrorKind};
use crate::ui::Ui;
use hg::operations::{FindRoot, FindRootError, FindRootErrorKind};
use hg::utils::files::get_bytes_from_path;
use std::path::PathBuf;

pub const HELP_TEXT: &str = "
Print the root directory of the current repository.

Returns 0 on success.
";

pub struct RootCommand {
    ui: Ui,
}

impl RootCommand {
    pub fn new() -> Self {
        RootCommand { ui: Ui::new() }
    }

    fn display_found_path(
        &self,
        path_buf: PathBuf,
    ) -> Result<(), CommandError> {
        let bytes = get_bytes_from_path(path_buf);

        // TODO use formating macro
        self.ui.write_stdout(&[bytes.as_slice(), b"\n"].concat())?;

        Err(CommandErrorKind::Ok.into())
    }

    fn display_error(&self, error: FindRootError) -> Result<(), CommandError> {
        match error.kind {
            FindRootErrorKind::RootNotFound(path) => {
                let bytes = get_bytes_from_path(path);

                // TODO use formating macro
                self.ui.write_stderr(
                    &[
                        b"abort: no repository found in '",
                        bytes.as_slice(),
                        b"' (.hg not found)!\n",
                    ]
                    .concat(),
                )?;

                Err(CommandErrorKind::RootNotFound.into())
            }
            FindRootErrorKind::GetCurrentDirError(e) => {
                // TODO use formating macro
                self.ui.write_stderr(
                    &[
                        b"abort: error getting current working directory: ",
                        e.to_string().as_bytes(),
                        b"\n",
                    ]
                    .concat(),
                )?;

                Err(CommandErrorKind::CurrentDirNotFound.into())
            }
        }
    }
}

impl Command for RootCommand {
    fn run(&self) -> Result<(), CommandError> {
        match FindRoot::new().run() {
            Ok(path_buf) => self.display_found_path(path_buf),
            Err(e) => self.display_error(e),
        }
    }
}