Patchwork D9874: rust: remove `FooError` structs with only `kind: FooErrorKind` enum field

login
register
mail settings
Submitter phabricator
Date Jan. 26, 2021, 8 p.m.
Message ID <differential-rev-PHID-DREV-qr2l5kfi63riwrchq7mf-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48187/
State Superseded
Headers show

Comments

phabricator - Jan. 26, 2021, 8 p.m.
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Use the enum directly as `FooError` instead.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D9874

AFFECTED FILES
  rust/hg-core/src/operations/cat.rs
  rust/hg-core/src/operations/debugdata.rs
  rust/hg-core/src/operations/find_root.rs
  rust/hg-core/src/operations/list_tracked_files.rs
  rust/hg-core/src/operations/mod.rs
  rust/rhg/src/commands/cat.rs
  rust/rhg/src/commands/debugdata.rs
  rust/rhg/src/commands/files.rs
  rust/rhg/src/error.rs

CHANGE DETAILS




To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/rust/rhg/src/error.rs b/rust/rhg/src/error.rs
--- a/rust/rhg/src/error.rs
+++ b/rust/rhg/src/error.rs
@@ -1,7 +1,7 @@ 
 use crate::exitcode;
 use crate::ui::UiError;
 use format_bytes::format_bytes;
-use hg::operations::{FindRootError, FindRootErrorKind};
+use hg::operations::FindRootError;
 use hg::requirements::RequirementsError;
 use hg::utils::files::get_bytes_from_path;
 use std::convert::From;
@@ -9,7 +9,7 @@ 
 
 /// The kind of command error
 #[derive(Debug)]
-pub enum CommandErrorKind {
+pub enum CommandError {
     /// The root of the repository cannot be found
     RootNotFound(PathBuf),
     /// The current directory cannot be found
@@ -26,99 +26,76 @@ 
     Unimplemented,
 }
 
-impl CommandErrorKind {
+impl CommandError {
     pub fn get_exit_code(&self) -> exitcode::ExitCode {
         match self {
-            CommandErrorKind::RootNotFound(_) => exitcode::ABORT,
-            CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT,
-            CommandErrorKind::RequirementsError(
+            CommandError::RootNotFound(_) => exitcode::ABORT,
+            CommandError::CurrentDirNotFound(_) => exitcode::ABORT,
+            CommandError::RequirementsError(
                 RequirementsError::Unsupported { .. },
             ) => exitcode::UNIMPLEMENTED_COMMAND,
-            CommandErrorKind::RequirementsError(_) => exitcode::ABORT,
-            CommandErrorKind::StdoutError => exitcode::ABORT,
-            CommandErrorKind::StderrError => exitcode::ABORT,
-            CommandErrorKind::Abort(_) => exitcode::ABORT,
-            CommandErrorKind::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND,
+            CommandError::RequirementsError(_) => exitcode::ABORT,
+            CommandError::StdoutError => exitcode::ABORT,
+            CommandError::StderrError => exitcode::ABORT,
+            CommandError::Abort(_) => exitcode::ABORT,
+            CommandError::Unimplemented => exitcode::UNIMPLEMENTED_COMMAND,
         }
     }
 
-    /// Return the message corresponding to the error kind if any
+    /// Return the message corresponding to the error if any
     pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
         match self {
-            CommandErrorKind::RootNotFound(path) => {
+            CommandError::RootNotFound(path) => {
                 let bytes = get_bytes_from_path(path);
                 Some(format_bytes!(
                     b"abort: no repository found in '{}' (.hg not found)!\n",
                     bytes.as_slice()
                 ))
             }
-            CommandErrorKind::CurrentDirNotFound(e) => Some(format_bytes!(
+            CommandError::CurrentDirNotFound(e) => Some(format_bytes!(
                 b"abort: error getting current working directory: {}\n",
                 e.to_string().as_bytes(),
             )),
-            CommandErrorKind::RequirementsError(
-                RequirementsError::Corrupted,
-            ) => Some(
-                "abort: .hg/requires is corrupted\n".as_bytes().to_owned(),
-            ),
-            CommandErrorKind::Abort(message) => message.to_owned(),
+            CommandError::RequirementsError(RequirementsError::Corrupted) => {
+                Some(
+                    "abort: .hg/requires is corrupted\n".as_bytes().to_owned(),
+                )
+            }
+            CommandError::Abort(message) => message.to_owned(),
             _ => None,
         }
     }
-}
 
-/// The error type for the Command trait
-#[derive(Debug)]
-pub struct CommandError {
-    pub kind: CommandErrorKind,
-}
-
-impl CommandError {
     /// Exist the process with the corresponding exit code.
     pub fn exit(&self) {
-        std::process::exit(self.kind.get_exit_code())
-    }
-
-    /// Return the message corresponding to the command error if any
-    pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
-        self.kind.get_error_message_bytes()
-    }
-}
-
-impl From<CommandErrorKind> for CommandError {
-    fn from(kind: CommandErrorKind) -> Self {
-        CommandError { kind }
+        std::process::exit(self.get_exit_code())
     }
 }
 
 impl From<UiError> for CommandError {
     fn from(error: UiError) -> Self {
-        CommandError {
-            kind: match error {
-                UiError::StdoutError(_) => CommandErrorKind::StdoutError,
-                UiError::StderrError(_) => CommandErrorKind::StderrError,
-            },
+        match error {
+            UiError::StdoutError(_) => CommandError::StdoutError,
+            UiError::StderrError(_) => CommandError::StderrError,
         }
     }
 }
 
 impl From<FindRootError> for CommandError {
     fn from(err: FindRootError) -> Self {
-        match err.kind {
-            FindRootErrorKind::RootNotFound(path) => CommandError {
-                kind: CommandErrorKind::RootNotFound(path),
-            },
-            FindRootErrorKind::GetCurrentDirError(e) => CommandError {
-                kind: CommandErrorKind::CurrentDirNotFound(e),
-            },
+        match err {
+            FindRootError::RootNotFound(path) => {
+                CommandError::RootNotFound(path)
+            }
+            FindRootError::GetCurrentDirError(e) => {
+                CommandError::CurrentDirNotFound(e)
+            }
         }
     }
 }
 
 impl From<RequirementsError> for CommandError {
     fn from(err: RequirementsError) -> Self {
-        CommandError {
-            kind: CommandErrorKind::RequirementsError(err),
-        }
+        CommandError::RequirementsError(err)
     }
 }
diff --git a/rust/rhg/src/commands/files.rs b/rust/rhg/src/commands/files.rs
--- a/rust/rhg/src/commands/files.rs
+++ b/rust/rhg/src/commands/files.rs
@@ -1,14 +1,9 @@ 
 use crate::commands::Command;
-use crate::error::{CommandError, CommandErrorKind};
+use crate::error::CommandError;
 use crate::ui::utf8_to_local;
 use crate::ui::Ui;
-use hg::operations::{
-    list_rev_tracked_files, ListRevTrackedFilesError,
-    ListRevTrackedFilesErrorKind,
-};
-use hg::operations::{
-    Dirstate, ListDirstateTrackedFilesError, ListDirstateTrackedFilesErrorKind,
-};
+use hg::operations::{list_rev_tracked_files, ListRevTrackedFilesError};
+use hg::operations::{Dirstate, ListDirstateTrackedFilesError};
 use hg::repo::Repo;
 use hg::utils::files::{get_bytes_from_path, relativize_path};
 use hg::utils::hg_path::{HgPath, HgPathBuf};
@@ -35,7 +30,7 @@ 
         files: impl IntoIterator<Item = &'a HgPath>,
     ) -> Result<(), CommandError> {
         let cwd = std::env::current_dir()
-            .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
+            .or_else(|e| Err(CommandError::CurrentDirNotFound(e)))?;
         let rooted_cwd = cwd
             .strip_prefix(repo.working_directory_path())
             .expect("cwd was already checked within the repository");
@@ -68,75 +63,65 @@ 
     }
 }
 
-/// Convert `ListRevTrackedFilesErrorKind` to `CommandError`
+/// Convert `ListRevTrackedFilesError` to `CommandError`
 fn map_rev_error(rev: &str, err: ListRevTrackedFilesError) -> CommandError {
-    CommandError {
-        kind: match err.kind {
-            ListRevTrackedFilesErrorKind::IoError(err) => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!("abort: {}\n", err)).into(),
+    match err {
+        ListRevTrackedFilesError::IoError(err) => CommandError::Abort(Some(
+            utf8_to_local(&format!("abort: {}\n", err)).into(),
+        )),
+        ListRevTrackedFilesError::InvalidRevision => {
+            CommandError::Abort(Some(
+                utf8_to_local(&format!(
+                    "abort: invalid revision identifier {}\n",
+                    rev
                 ))
-            }
-            ListRevTrackedFilesErrorKind::InvalidRevision => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!(
-                        "abort: invalid revision identifier {}\n",
-                        rev
-                    ))
-                    .into(),
-                ))
-            }
-            ListRevTrackedFilesErrorKind::AmbiguousPrefix => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!(
-                        "abort: ambiguous revision identifier {}\n",
-                        rev
-                    ))
-                    .into(),
+                .into(),
+            ))
+        }
+        ListRevTrackedFilesError::AmbiguousPrefix => {
+            CommandError::Abort(Some(
+                utf8_to_local(&format!(
+                    "abort: ambiguous revision identifier {}\n",
+                    rev
                 ))
-            }
-            ListRevTrackedFilesErrorKind::UnsuportedRevlogVersion(version) => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!(
-                        "abort: unsupported revlog version {}\n",
-                        version
-                    ))
-                    .into(),
+                .into(),
+            ))
+        }
+        ListRevTrackedFilesError::UnsuportedRevlogVersion(version) => {
+            CommandError::Abort(Some(
+                utf8_to_local(&format!(
+                    "abort: unsupported revlog version {}\n",
+                    version
                 ))
-            }
-            ListRevTrackedFilesErrorKind::CorruptedRevlog => {
-                CommandErrorKind::Abort(Some(
-                    "abort: corrupted revlog\n".into(),
+                .into(),
+            ))
+        }
+        ListRevTrackedFilesError::CorruptedRevlog => {
+            CommandError::Abort(Some("abort: corrupted revlog\n".into()))
+        }
+        ListRevTrackedFilesError::UnknowRevlogDataFormat(format) => {
+            CommandError::Abort(Some(
+                utf8_to_local(&format!(
+                    "abort: unknow revlog dataformat {:?}\n",
+                    format
                 ))
-            }
-            ListRevTrackedFilesErrorKind::UnknowRevlogDataFormat(format) => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!(
-                        "abort: unknow revlog dataformat {:?}\n",
-                        format
-                    ))
-                    .into(),
-                ))
-            }
-        },
+                .into(),
+            ))
+        }
     }
 }
 
 /// Convert `ListDirstateTrackedFilesError` to `CommandError`
 fn map_dirstate_error(err: ListDirstateTrackedFilesError) -> CommandError {
-    CommandError {
-        kind: match err.kind {
-            ListDirstateTrackedFilesErrorKind::IoError(err) => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!("abort: {}\n", err)).into(),
-                ))
-            }
-            ListDirstateTrackedFilesErrorKind::ParseError(_) => {
-                CommandErrorKind::Abort(Some(
-                    // TODO find a better error message
-                    b"abort: parse error\n".to_vec(),
-                ))
-            }
-        },
+    match err {
+        ListDirstateTrackedFilesError::IoError(err) => CommandError::Abort(
+            Some(utf8_to_local(&format!("abort: {}\n", err)).into()),
+        ),
+        ListDirstateTrackedFilesError::ParseError(_) => {
+            CommandError::Abort(Some(
+                // TODO find a better error message
+                b"abort: parse error\n".to_vec(),
+            ))
+        }
     }
 }
diff --git a/rust/rhg/src/commands/debugdata.rs b/rust/rhg/src/commands/debugdata.rs
--- a/rust/rhg/src/commands/debugdata.rs
+++ b/rust/rhg/src/commands/debugdata.rs
@@ -1,10 +1,8 @@ 
 use crate::commands::Command;
-use crate::error::{CommandError, CommandErrorKind};
+use crate::error::CommandError;
 use crate::ui::utf8_to_local;
 use crate::ui::Ui;
-use hg::operations::{
-    debug_data, DebugDataError, DebugDataErrorKind, DebugDataKind,
-};
+use hg::operations::{debug_data, DebugDataError, DebugDataKind};
 use hg::repo::Repo;
 use micro_timer::timed;
 
@@ -40,52 +38,44 @@ 
 
 /// Convert operation errors to command errors
 fn to_command_error(rev: &str, err: DebugDataError) -> CommandError {
-    match err.kind {
-        DebugDataErrorKind::IoError(err) => CommandError {
-            kind: CommandErrorKind::Abort(Some(
-                utf8_to_local(&format!("abort: {}\n", err)).into(),
-            )),
-        },
-        DebugDataErrorKind::InvalidRevision => CommandError {
-            kind: CommandErrorKind::Abort(Some(
-                utf8_to_local(&format!(
-                    "abort: invalid revision identifier{}\n",
-                    rev
-                ))
-                .into(),
-            )),
-        },
-        DebugDataErrorKind::AmbiguousPrefix => CommandError {
-            kind: CommandErrorKind::Abort(Some(
-                utf8_to_local(&format!(
-                    "abort: ambiguous revision identifier{}\n",
-                    rev
-                ))
-                .into(),
-            )),
-        },
-        DebugDataErrorKind::UnsuportedRevlogVersion(version) => CommandError {
-            kind: CommandErrorKind::Abort(Some(
+    match err {
+        DebugDataError::IoError(err) => CommandError::Abort(Some(
+            utf8_to_local(&format!("abort: {}\n", err)).into(),
+        )),
+        DebugDataError::InvalidRevision => CommandError::Abort(Some(
+            utf8_to_local(&format!(
+                "abort: invalid revision identifier{}\n",
+                rev
+            ))
+            .into(),
+        )),
+        DebugDataError::AmbiguousPrefix => CommandError::Abort(Some(
+            utf8_to_local(&format!(
+                "abort: ambiguous revision identifier{}\n",
+                rev
+            ))
+            .into(),
+        )),
+        DebugDataError::UnsuportedRevlogVersion(version) => {
+            CommandError::Abort(Some(
                 utf8_to_local(&format!(
                     "abort: unsupported revlog version {}\n",
                     version
                 ))
                 .into(),
-            )),
-        },
-        DebugDataErrorKind::CorruptedRevlog => CommandError {
-            kind: CommandErrorKind::Abort(Some(
-                "abort: corrupted revlog\n".into(),
-            )),
-        },
-        DebugDataErrorKind::UnknowRevlogDataFormat(format) => CommandError {
-            kind: CommandErrorKind::Abort(Some(
+            ))
+        }
+        DebugDataError::CorruptedRevlog => {
+            CommandError::Abort(Some("abort: corrupted revlog\n".into()))
+        }
+        DebugDataError::UnknowRevlogDataFormat(format) => {
+            CommandError::Abort(Some(
                 utf8_to_local(&format!(
                     "abort: unknow revlog dataformat {:?}\n",
                     format
                 ))
                 .into(),
-            )),
-        },
+            ))
+        }
     }
 }
diff --git a/rust/rhg/src/commands/cat.rs b/rust/rhg/src/commands/cat.rs
--- a/rust/rhg/src/commands/cat.rs
+++ b/rust/rhg/src/commands/cat.rs
@@ -1,8 +1,8 @@ 
 use crate::commands::Command;
-use crate::error::{CommandError, CommandErrorKind};
+use crate::error::CommandError;
 use crate::ui::utf8_to_local;
 use crate::ui::Ui;
-use hg::operations::{cat, CatRevError, CatRevErrorKind};
+use hg::operations::{cat, CatRevError};
 use hg::repo::Repo;
 use hg::utils::hg_path::HgPathBuf;
 use micro_timer::timed;
@@ -34,16 +34,16 @@ 
         let repo = Repo::find()?;
         repo.check_requirements()?;
         let cwd = std::env::current_dir()
-            .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
+            .or_else(|e| Err(CommandError::CurrentDirNotFound(e)))?;
 
         let mut files = vec![];
         for file in self.files.iter() {
             let normalized = cwd.join(&file);
             let stripped = normalized
                 .strip_prefix(&repo.working_directory_path())
-                .or(Err(CommandErrorKind::Abort(None)))?;
+                .or(Err(CommandError::Abort(None)))?;
             let hg_file = HgPathBuf::try_from(stripped.to_path_buf())
-                .or(Err(CommandErrorKind::Abort(None)))?;
+                .or(Err(CommandError::Abort(None)))?;
             files.push(hg_file);
         }
 
@@ -53,53 +53,51 @@ 
                     .map_err(|e| map_rev_error(rev, e))?;
                 self.display(ui, &data)
             }
-            None => Err(CommandErrorKind::Unimplemented.into()),
+            None => Err(CommandError::Unimplemented.into()),
         }
     }
 }
 
-/// Convert `CatRevErrorKind` to `CommandError`
+/// Convert `CatRevError` to `CommandError`
 fn map_rev_error(rev: &str, err: CatRevError) -> CommandError {
-    CommandError {
-        kind: match err.kind {
-            CatRevErrorKind::IoError(err) => CommandErrorKind::Abort(Some(
-                utf8_to_local(&format!("abort: {}\n", err)).into(),
-            )),
-            CatRevErrorKind::InvalidRevision => CommandErrorKind::Abort(Some(
+    match err {
+        CatRevError::IoError(err) => CommandError::Abort(Some(
+            utf8_to_local(&format!("abort: {}\n", err)).into(),
+        )),
+        CatRevError::InvalidRevision => CommandError::Abort(Some(
+            utf8_to_local(&format!(
+                "abort: invalid revision identifier {}\n",
+                rev
+            ))
+            .into(),
+        )),
+        CatRevError::AmbiguousPrefix => CommandError::Abort(Some(
+            utf8_to_local(&format!(
+                "abort: ambiguous revision identifier {}\n",
+                rev
+            ))
+            .into(),
+        )),
+        CatRevError::UnsuportedRevlogVersion(version) => {
+            CommandError::Abort(Some(
                 utf8_to_local(&format!(
-                    "abort: invalid revision identifier {}\n",
-                    rev
-                ))
-                .into(),
-            )),
-            CatRevErrorKind::AmbiguousPrefix => CommandErrorKind::Abort(Some(
-                utf8_to_local(&format!(
-                    "abort: ambiguous revision identifier {}\n",
-                    rev
+                    "abort: unsupported revlog version {}\n",
+                    version
                 ))
                 .into(),
-            )),
-            CatRevErrorKind::UnsuportedRevlogVersion(version) => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!(
-                        "abort: unsupported revlog version {}\n",
-                        version
-                    ))
-                    .into(),
+            ))
+        }
+        CatRevError::CorruptedRevlog => {
+            CommandError::Abort(Some("abort: corrupted revlog\n".into()))
+        }
+        CatRevError::UnknowRevlogDataFormat(format) => {
+            CommandError::Abort(Some(
+                utf8_to_local(&format!(
+                    "abort: unknow revlog dataformat {:?}\n",
+                    format
                 ))
-            }
-            CatRevErrorKind::CorruptedRevlog => CommandErrorKind::Abort(Some(
-                "abort: corrupted revlog\n".into(),
-            )),
-            CatRevErrorKind::UnknowRevlogDataFormat(format) => {
-                CommandErrorKind::Abort(Some(
-                    utf8_to_local(&format!(
-                        "abort: unknow revlog dataformat {:?}\n",
-                        format
-                    ))
-                    .into(),
-                ))
-            }
-        },
+                .into(),
+            ))
+        }
     }
 }
diff --git a/rust/hg-core/src/operations/mod.rs b/rust/hg-core/src/operations/mod.rs
--- a/rust/hg-core/src/operations/mod.rs
+++ b/rust/hg-core/src/operations/mod.rs
@@ -7,17 +7,10 @@ 
 mod dirstate_status;
 mod find_root;
 mod list_tracked_files;
-pub use cat::{cat, CatRevError, CatRevErrorKind};
-pub use debugdata::{
-    debug_data, DebugDataError, DebugDataErrorKind, DebugDataKind,
-};
-pub use find_root::{
-    find_root, find_root_from_path, FindRootError, FindRootErrorKind,
-};
+pub use cat::{cat, CatRevError};
+pub use debugdata::{debug_data, DebugDataError, DebugDataKind};
+pub use find_root::{find_root, find_root_from_path, FindRootError};
 pub use list_tracked_files::{
     list_rev_tracked_files, FilesForRev, ListRevTrackedFilesError,
-    ListRevTrackedFilesErrorKind,
 };
-pub use list_tracked_files::{
-    Dirstate, ListDirstateTrackedFilesError, ListDirstateTrackedFilesErrorKind,
-};
+pub use list_tracked_files::{Dirstate, ListDirstateTrackedFilesError};
diff --git a/rust/hg-core/src/operations/list_tracked_files.rs b/rust/hg-core/src/operations/list_tracked_files.rs
--- a/rust/hg-core/src/operations/list_tracked_files.rs
+++ b/rust/hg-core/src/operations/list_tracked_files.rs
@@ -16,34 +16,18 @@ 
 use rayon::prelude::*;
 use std::convert::From;
 
-/// Kind of error encountered by `ListDirstateTrackedFiles`
+/// Error type for `Dirstate` methods
 #[derive(Debug)]
-pub enum ListDirstateTrackedFilesErrorKind {
+pub enum ListDirstateTrackedFilesError {
     /// Error when reading the `dirstate` file
     IoError(std::io::Error),
     /// Error when parsing the `dirstate` file
     ParseError(DirstateParseError),
 }
 
-/// A `ListDirstateTrackedFiles` error
-#[derive(Debug)]
-pub struct ListDirstateTrackedFilesError {
-    /// Kind of error encountered by `ListDirstateTrackedFiles`
-    pub kind: ListDirstateTrackedFilesErrorKind,
-}
-
-impl From<ListDirstateTrackedFilesErrorKind>
-    for ListDirstateTrackedFilesError
-{
-    fn from(kind: ListDirstateTrackedFilesErrorKind) -> Self {
-        ListDirstateTrackedFilesError { kind }
-    }
-}
-
 impl From<std::io::Error> for ListDirstateTrackedFilesError {
     fn from(err: std::io::Error) -> Self {
-        let kind = ListDirstateTrackedFilesErrorKind::IoError(err);
-        ListDirstateTrackedFilesError { kind }
+        ListDirstateTrackedFilesError::IoError(err)
     }
 }
 
@@ -64,7 +48,7 @@ 
         &self,
     ) -> Result<Vec<&HgPath>, ListDirstateTrackedFilesError> {
         let (_, entries, _) = parse_dirstate(&self.content)
-            .map_err(ListDirstateTrackedFilesErrorKind::ParseError)?;
+            .map_err(ListDirstateTrackedFilesError::ParseError)?;
         let mut files: Vec<&HgPath> = entries
             .into_iter()
             .filter_map(|(path, entry)| match entry.state {
@@ -77,9 +61,9 @@ 
     }
 }
 
-/// Kind of error encountered by `ListRevTrackedFiles`
+/// Error type `list_rev_tracked_files`
 #[derive(Debug)]
-pub enum ListRevTrackedFilesErrorKind {
+pub enum ListRevTrackedFilesError {
     /// Error when reading a `revlog` file.
     IoError(std::io::Error),
     /// The revision has not been found.
@@ -94,42 +78,28 @@ 
     UnknowRevlogDataFormat(u8),
 }
 
-/// A `ListRevTrackedFiles` error
-#[derive(Debug)]
-pub struct ListRevTrackedFilesError {
-    /// Kind of error encountered by `ListRevTrackedFiles`
-    pub kind: ListRevTrackedFilesErrorKind,
-}
-
-impl From<ListRevTrackedFilesErrorKind> for ListRevTrackedFilesError {
-    fn from(kind: ListRevTrackedFilesErrorKind) -> Self {
-        ListRevTrackedFilesError { kind }
-    }
-}
-
 impl From<RevlogError> for ListRevTrackedFilesError {
     fn from(err: RevlogError) -> Self {
         match err {
             RevlogError::IoError(err) => {
-                ListRevTrackedFilesErrorKind::IoError(err)
+                ListRevTrackedFilesError::IoError(err)
             }
             RevlogError::UnsuportedVersion(version) => {
-                ListRevTrackedFilesErrorKind::UnsuportedRevlogVersion(version)
+                ListRevTrackedFilesError::UnsuportedRevlogVersion(version)
             }
             RevlogError::InvalidRevision => {
-                ListRevTrackedFilesErrorKind::InvalidRevision
+                ListRevTrackedFilesError::InvalidRevision
             }
             RevlogError::AmbiguousPrefix => {
-                ListRevTrackedFilesErrorKind::AmbiguousPrefix
+                ListRevTrackedFilesError::AmbiguousPrefix
             }
             RevlogError::Corrupted => {
-                ListRevTrackedFilesErrorKind::CorruptedRevlog
+                ListRevTrackedFilesError::CorruptedRevlog
             }
             RevlogError::UnknowDataFormat(format) => {
-                ListRevTrackedFilesErrorKind::UnknowRevlogDataFormat(format)
+                ListRevTrackedFilesError::UnknowRevlogDataFormat(format)
             }
         }
-        .into()
     }
 }
 
@@ -143,7 +113,7 @@ 
     let manifest = Manifest::open(repo)?;
     let changelog_entry = changelog.get_rev(rev)?;
     let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
-        .or(Err(ListRevTrackedFilesErrorKind::CorruptedRevlog))?;
+        .or(Err(ListRevTrackedFilesError::CorruptedRevlog))?;
     let manifest_entry = manifest.get_node(manifest_node.into())?;
     Ok(FilesForRev(manifest_entry))
 }
diff --git a/rust/hg-core/src/operations/find_root.rs b/rust/hg-core/src/operations/find_root.rs
--- a/rust/hg-core/src/operations/find_root.rs
+++ b/rust/hg-core/src/operations/find_root.rs
@@ -1,9 +1,8 @@ 
-use std::fmt;
 use std::path::{Path, PathBuf};
 
-/// Kind of error encoutered by FindRoot
+/// Error type for `find_root`
 #[derive(Debug)]
-pub enum FindRootErrorKind {
+pub enum FindRootError {
     /// Root of the repository has not been found
     /// Contains the current directory used by FindRoot
     RootNotFound(PathBuf),
@@ -12,28 +11,12 @@ 
     GetCurrentDirError(std::io::Error),
 }
 
-/// A FindRoot error
-#[derive(Debug)]
-pub struct FindRootError {
-    /// Kind of error encoutered by FindRoot
-    pub kind: FindRootErrorKind,
-}
-
-impl std::error::Error for FindRootError {}
-
-impl fmt::Display for FindRootError {
-    fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        unimplemented!()
-    }
-}
-
 /// Find the root of the repository
 /// by searching for a .hg directory in the process’ current directory and its
 /// ancestors
 pub fn find_root() -> Result<PathBuf, FindRootError> {
-    let current_dir = std::env::current_dir().map_err(|e| FindRootError {
-        kind: FindRootErrorKind::GetCurrentDirError(e),
-    })?;
+    let current_dir = std::env::current_dir()
+        .map_err(|e| FindRootError::GetCurrentDirError(e))?;
     Ok(find_root_from_path(&current_dir)?.into())
 }
 
@@ -48,9 +31,7 @@ 
             return Ok(ancestor);
         }
     }
-    Err(FindRootError {
-        kind: FindRootErrorKind::RootNotFound(start.into()),
-    })
+    Err(FindRootError::RootNotFound(start.into()))
 }
 
 #[cfg(test)]
@@ -68,10 +49,8 @@ 
 
         // TODO do something better
         assert!(match err {
-            FindRootError { kind } => match kind {
-                FindRootErrorKind::RootNotFound(p) => p == path.to_path_buf(),
-                _ => false,
-            },
+            FindRootError::RootNotFound(p) => p == path.to_path_buf(),
+            _ => false,
         })
     }
 
diff --git a/rust/hg-core/src/operations/debugdata.rs b/rust/hg-core/src/operations/debugdata.rs
--- a/rust/hg-core/src/operations/debugdata.rs
+++ b/rust/hg-core/src/operations/debugdata.rs
@@ -15,9 +15,9 @@ 
     Manifest,
 }
 
-/// Kind of error encountered by DebugData
+/// Error type for `debug_data`
 #[derive(Debug)]
-pub enum DebugDataErrorKind {
+pub enum DebugDataError {
     /// Error when reading a `revlog` file.
     IoError(std::io::Error),
     /// The revision has not been found.
@@ -32,45 +32,26 @@ 
     UnknowRevlogDataFormat(u8),
 }
 
-/// A DebugData error
-#[derive(Debug)]
-pub struct DebugDataError {
-    /// Kind of error encountered by DebugData
-    pub kind: DebugDataErrorKind,
-}
-
-impl From<DebugDataErrorKind> for DebugDataError {
-    fn from(kind: DebugDataErrorKind) -> Self {
-        DebugDataError { kind }
-    }
-}
-
 impl From<std::io::Error> for DebugDataError {
     fn from(err: std::io::Error) -> Self {
-        let kind = DebugDataErrorKind::IoError(err);
-        DebugDataError { kind }
+        DebugDataError::IoError(err)
     }
 }
 
 impl From<RevlogError> for DebugDataError {
     fn from(err: RevlogError) -> Self {
         match err {
-            RevlogError::IoError(err) => DebugDataErrorKind::IoError(err),
+            RevlogError::IoError(err) => DebugDataError::IoError(err),
             RevlogError::UnsuportedVersion(version) => {
-                DebugDataErrorKind::UnsuportedRevlogVersion(version)
-            }
-            RevlogError::InvalidRevision => {
-                DebugDataErrorKind::InvalidRevision
+                DebugDataError::UnsuportedRevlogVersion(version)
             }
-            RevlogError::AmbiguousPrefix => {
-                DebugDataErrorKind::AmbiguousPrefix
-            }
-            RevlogError::Corrupted => DebugDataErrorKind::CorruptedRevlog,
+            RevlogError::InvalidRevision => DebugDataError::InvalidRevision,
+            RevlogError::AmbiguousPrefix => DebugDataError::AmbiguousPrefix,
+            RevlogError::Corrupted => DebugDataError::CorruptedRevlog,
             RevlogError::UnknowDataFormat(format) => {
-                DebugDataErrorKind::UnknowRevlogDataFormat(format)
+                DebugDataError::UnknowRevlogDataFormat(format)
             }
         }
-        .into()
     }
 }
 
diff --git a/rust/hg-core/src/operations/cat.rs b/rust/hg-core/src/operations/cat.rs
--- a/rust/hg-core/src/operations/cat.rs
+++ b/rust/hg-core/src/operations/cat.rs
@@ -20,9 +20,9 @@ 
 
 const METADATA_DELIMITER: [u8; 2] = [b'\x01', b'\n'];
 
-/// Kind of error encountered by `CatRev`
+/// Error type for `cat`
 #[derive(Debug)]
-pub enum CatRevErrorKind {
+pub enum CatRevError {
     /// Error when reading a `revlog` file.
     IoError(std::io::Error),
     /// The revision has not been found.
@@ -37,34 +37,20 @@ 
     UnknowRevlogDataFormat(u8),
 }
 
-/// A `CatRev` error
-#[derive(Debug)]
-pub struct CatRevError {
-    /// Kind of error encountered by `CatRev`
-    pub kind: CatRevErrorKind,
-}
-
-impl From<CatRevErrorKind> for CatRevError {
-    fn from(kind: CatRevErrorKind) -> Self {
-        CatRevError { kind }
-    }
-}
-
 impl From<RevlogError> for CatRevError {
     fn from(err: RevlogError) -> Self {
         match err {
-            RevlogError::IoError(err) => CatRevErrorKind::IoError(err),
+            RevlogError::IoError(err) => CatRevError::IoError(err),
             RevlogError::UnsuportedVersion(version) => {
-                CatRevErrorKind::UnsuportedRevlogVersion(version)
+                CatRevError::UnsuportedRevlogVersion(version)
             }
-            RevlogError::InvalidRevision => CatRevErrorKind::InvalidRevision,
-            RevlogError::AmbiguousPrefix => CatRevErrorKind::AmbiguousPrefix,
-            RevlogError::Corrupted => CatRevErrorKind::CorruptedRevlog,
+            RevlogError::InvalidRevision => CatRevError::InvalidRevision,
+            RevlogError::AmbiguousPrefix => CatRevError::AmbiguousPrefix,
+            RevlogError::Corrupted => CatRevError::CorruptedRevlog,
             RevlogError::UnknowDataFormat(format) => {
-                CatRevErrorKind::UnknowRevlogDataFormat(format)
+                CatRevError::UnknowRevlogDataFormat(format)
             }
         }
-        .into()
     }
 }
 
@@ -83,7 +69,7 @@ 
     let manifest = Manifest::open(repo)?;
     let changelog_entry = changelog.get_rev(rev)?;
     let manifest_node = Node::from_hex(&changelog_entry.manifest_node()?)
-        .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
+        .map_err(|_| CatRevError::CorruptedRevlog)?;
     let manifest_entry = manifest.get_node(manifest_node.into())?;
     let mut bytes = vec![];
 
@@ -96,7 +82,7 @@ 
                 let file_log =
                     Revlog::open(repo, &index_path, Some(&data_path))?;
                 let file_node = Node::from_hex(node_bytes)
-                    .map_err(|_| CatRevErrorKind::CorruptedRevlog)?;
+                    .map_err(|_| CatRevError::CorruptedRevlog)?;
                 let file_rev = file_log.get_node_rev(file_node.into())?;
                 let data = file_log.get_rev_data(file_rev)?;
                 if data.starts_with(&METADATA_DELIMITER) {