rust/hg-core/src/operations/list_tracked_files.rs
changeset 45535 72b7d58d6e35
parent 45436 1b3197047f5c
child 45536 639f33f22faf
equal deleted inserted replaced
45534:4f11a67a12fb 45535:72b7d58d6e35
     3 // Copyright 2020 Antoine Cezar <antoine.cezar@octobus.net>
     3 // Copyright 2020 Antoine Cezar <antoine.cezar@octobus.net>
     4 //
     4 //
     5 // This software may be used and distributed according to the terms of the
     5 // This software may be used and distributed according to the terms of the
     6 // GNU General Public License version 2 or any later version.
     6 // GNU General Public License version 2 or any later version.
     7 
     7 
     8 use super::find_root;
       
     9 use crate::dirstate::parsers::parse_dirstate;
     8 use crate::dirstate::parsers::parse_dirstate;
    10 use crate::utils::hg_path::HgPath;
     9 use crate::utils::hg_path::HgPath;
    11 use crate::{DirstateParseError, EntryState};
    10 use crate::{DirstateParseError, EntryState};
    12 use rayon::prelude::*;
    11 use rayon::prelude::*;
    13 use std::convert::From;
    12 use std::convert::From;
    14 use std::fmt;
    13 use std::fmt;
    15 use std::fs;
    14 use std::fs;
    16 use std::io;
    15 use std::ops::Deref;
    17 use std::path::{Path, PathBuf};
    16 use std::path::{Path, PathBuf};
    18 
    17 
    19 /// Kind of error encoutered by ListTrackedFiles
    18 /// Kind of error encountered by `ListDirstateTrackedFiles`
    20 #[derive(Debug)]
    19 #[derive(Debug)]
    21 pub enum ListTrackedFilesErrorKind {
    20 pub enum ListDirstateTrackedFilesErrorKind {
       
    21     /// Error when reading the `dirstate` file
       
    22     IoError(std::io::Error),
       
    23     /// Error when parsing the `dirstate` file
    22     ParseError(DirstateParseError),
    24     ParseError(DirstateParseError),
    23 }
    25 }
    24 
    26 
    25 /// A ListTrackedFiles error
    27 /// A `ListDirstateTrackedFiles` error
    26 #[derive(Debug)]
    28 #[derive(Debug)]
    27 pub struct ListTrackedFilesError {
    29 pub struct ListDirstateTrackedFilesError {
    28     /// Kind of error encoutered by ListTrackedFiles
    30     /// Kind of error encountered by `ListDirstateTrackedFiles`
    29     pub kind: ListTrackedFilesErrorKind,
    31     pub kind: ListDirstateTrackedFilesErrorKind,
    30 }
    32 }
    31 
    33 
    32 impl std::error::Error for ListTrackedFilesError {}
    34 impl std::error::Error for ListDirstateTrackedFilesError {}
    33 
    35 
    34 impl fmt::Display for ListTrackedFilesError {
    36 impl fmt::Display for ListDirstateTrackedFilesError {
    35     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
    37     fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
    36         unimplemented!()
    38         unimplemented!()
    37     }
    39     }
    38 }
    40 }
    39 
    41 
    40 impl From<ListTrackedFilesErrorKind> for ListTrackedFilesError {
    42 impl From<ListDirstateTrackedFilesErrorKind>
    41     fn from(kind: ListTrackedFilesErrorKind) -> Self {
    43     for ListDirstateTrackedFilesError
    42         ListTrackedFilesError { kind }
    44 {
       
    45     fn from(kind: ListDirstateTrackedFilesErrorKind) -> Self {
       
    46         ListDirstateTrackedFilesError { kind }
    43     }
    47     }
    44 }
    48 }
    45 
    49 
    46 /// List files under Mercurial control in the working directory
    50 impl From<std::io::Error> for ListDirstateTrackedFilesError {
    47 pub struct ListTrackedFiles {
    51     fn from(err: std::io::Error) -> Self {
    48     root: PathBuf,
    52         let kind = ListDirstateTrackedFilesErrorKind::IoError(err);
    49 }
    53         ListDirstateTrackedFilesError { kind }
    50 
       
    51 impl ListTrackedFiles {
       
    52     pub fn new() -> Result<Self, find_root::FindRootError> {
       
    53         let root = find_root::FindRoot::new().run()?;
       
    54         Ok(ListTrackedFiles { root })
       
    55     }
       
    56 
       
    57     /// Load the tracked files data from disk
       
    58     pub fn load(&self) -> Result<ListDirstateTrackedFiles, io::Error> {
       
    59         let dirstate = &self.root.join(".hg/dirstate");
       
    60         let content = fs::read(&dirstate)?;
       
    61         Ok(ListDirstateTrackedFiles { content })
       
    62     }
       
    63 
       
    64     /// Returns the repository root directory
       
    65     /// TODO I think this is a crutch that creates a dependency that should not
       
    66     /// be there. Operations that need the root of the repository should get
       
    67     /// it themselves, probably in a lazy fashion. But this would make the
       
    68     /// current series even larger, so this is simplified for now.
       
    69     pub fn get_root(&self) -> &Path {
       
    70         &self.root
       
    71     }
    54     }
    72 }
    55 }
    73 
    56 
    74 /// List files under Mercurial control in the working directory
    57 /// List files under Mercurial control in the working directory
    75 /// by reading the dirstate
    58 /// by reading the dirstate
    76 pub struct ListDirstateTrackedFiles {
    59 pub struct ListDirstateTrackedFiles {
       
    60     /// The `dirstate` content.
    77     content: Vec<u8>,
    61     content: Vec<u8>,
    78 }
    62 }
    79 
    63 
    80 impl ListDirstateTrackedFiles {
    64 impl ListDirstateTrackedFiles {
    81     pub fn run(&self) -> Result<Vec<&HgPath>, ListTrackedFilesError> {
    65     pub fn new(root: &PathBuf) -> Result<Self, ListDirstateTrackedFilesError> {
       
    66         let dirstate = root.join(".hg/dirstate");
       
    67         let content = fs::read(&dirstate)?;
       
    68         Ok(Self { content })
       
    69     }
       
    70 
       
    71     pub fn run(
       
    72         &mut self,
       
    73     ) -> Result<Vec<&HgPath>, ListDirstateTrackedFilesError> {
    82         let (_, entries, _) = parse_dirstate(&self.content)
    74         let (_, entries, _) = parse_dirstate(&self.content)
    83             .map_err(ListTrackedFilesErrorKind::ParseError)?;
    75             .map_err(ListDirstateTrackedFilesErrorKind::ParseError)?;
    84         let mut files: Vec<&HgPath> = entries
    76         let mut files: Vec<&HgPath> = entries
    85             .into_iter()
    77             .into_iter()
    86             .filter_map(|(path, entry)| match entry.state {
    78             .filter_map(|(path, entry)| match entry.state {
    87                 EntryState::Removed => None,
    79                 EntryState::Removed => None,
    88                 _ => Some(path),
    80                 _ => Some(path),