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 @@ -1,10 +1,21 @@ +use super::find_root; use super::Operation; +use crate::dirstate::parsers::parse_dirstate; use crate::utils::hg_path::HgPathBuf; +use crate::DirstateParseError; +use rayon::prelude::*; +use std::convert::From; use std::fmt; +use std::fs; +use std::io; /// Kind of error encoutered by ListTrackedFiles #[derive(Debug)] -pub enum ListTrackedFilesErrorKind {} +pub enum ListTrackedFilesErrorKind { + FindRootError(find_root::FindRootError), + IoError(io::Error), + ParseError(DirstateParseError), +} /// A ListTrackedFiles error #[derive(Debug)] @@ -21,14 +32,37 @@ } } +impl From for ListTrackedFilesError { + fn from(kind: ListTrackedFilesErrorKind) -> Self { + ListTrackedFilesError { kind } + } +} + /// List files under Mercurial control in the working directory /// by reading the dirstate at .hg/dirstate pub struct ListTrackedFiles {} +impl ListTrackedFiles { + pub fn new() -> Self { + ListTrackedFiles {} + } +} + impl Operation> for ListTrackedFiles { type Error = ListTrackedFilesError; fn run(&self) -> Result, Self::Error> { - unimplemented!() + let root = find_root::FindRoot::new() + .run() + .map_err(ListTrackedFilesErrorKind::FindRootError)?; + let dirstate = &root.join(".hg/dirstate"); + let dirstate_content = + fs::read(&dirstate).map_err(ListTrackedFilesErrorKind::IoError)?; + let (_, entries, _) = parse_dirstate(&dirstate_content) + .map_err(ListTrackedFilesErrorKind::ParseError)?; + let mut files: Vec<_> = + entries.into_iter().map(|(path, _)| path).collect(); + files.par_sort_unstable(); + Ok(files) } } 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 @@ -1,6 +1,9 @@ mod find_root; mod list_tracked_files; pub use find_root::{FindRoot, FindRootError, FindRootErrorKind}; +pub use list_tracked_files::{ + ListTrackedFiles, ListTrackedFilesError, ListTrackedFilesErrorKind, +}; /// An interface for high-level hg operations. ///