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 @@ -6,6 +6,9 @@ mod dirstate_status; mod find_root; mod list_tracked_files; +pub use debugdata::{ + DebugData, DebugDataError, DebugDataErrorKind, DebugDataKind, +}; pub use find_root::{FindRoot, FindRootError, FindRootErrorKind}; pub use list_tracked_files::{ ListTrackedFiles, ListTrackedFilesError, ListTrackedFilesErrorKind, diff --git a/rust/rhg/src/commands.rs b/rust/rhg/src/commands.rs --- a/rust/rhg/src/commands.rs +++ b/rust/rhg/src/commands.rs @@ -1,3 +1,4 @@ +pub mod debugdata; pub mod files; pub mod root; use crate::error::CommandError; diff --git a/rust/rhg/src/commands/debugdata.rs b/rust/rhg/src/commands/debugdata.rs new file mode 100644 --- /dev/null +++ b/rust/rhg/src/commands/debugdata.rs @@ -0,0 +1,80 @@ +use crate::commands::Command; +use crate::error::{CommandError, CommandErrorKind}; +use crate::ui::utf8_to_local; +use crate::ui::Ui; +use hg::operations::{ + DebugData, DebugDataError, DebugDataErrorKind, DebugDataKind, +}; + +pub const HELP_TEXT: &str = " +Dump the contents of a data file revision +"; + +pub struct DebugDataCommand<'a> { + rev: &'a str, + kind: DebugDataKind, +} + +impl<'a> DebugDataCommand<'a> { + pub fn new(rev: &'a str, kind: DebugDataKind) -> Self { + DebugDataCommand { rev, kind } + } +} + +impl<'a> Command for DebugDataCommand<'a> { + fn run(&self, ui: &Ui) -> Result<(), CommandError> { + let mut operation = DebugData::new(self.rev, self.kind); + let data = + operation.run().map_err(|e| to_command_error(self.rev, e))?; + + let mut stdout = ui.stdout_buffer(); + stdout.write_all(&data)?; + stdout.flush()?; + + Ok(()) + } +} + +/// Convert operation errors to command errors +fn to_command_error(rev: &str, err: DebugDataError) -> CommandError { + match err.kind { + DebugDataErrorKind::FindRootError(err) => CommandError::from(err), + 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::UnsuportedRevlogVersion(version) => CommandError { + kind: CommandErrorKind::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( + utf8_to_local(&format!( + "abort: unknow revlog dataformat {:?}\n", + format + )) + .into(), + )), + }, + } +} diff --git a/rust/rhg/src/ui.rs b/rust/rhg/src/ui.rs --- a/rust/rhg/src/ui.rs +++ b/rust/rhg/src/ui.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::io; use std::io::{ErrorKind, Write}; @@ -103,3 +104,9 @@ } Err(UiError::StdoutError(error)) } + +pub fn utf8_to_local(s: &str) -> Cow<[u8]> { + // TODO encode for the user's system // + let bytes = s.as_bytes(); + Cow::Borrowed(bytes) +}