rust/hg-core/src/dirstate_tree/dispatch.rs
changeset 48069 3d0a9c6e614d
parent 48068 bf8837e3d7ce
child 48071 adb367f0e9a2
equal deleted inserted replaced
48068:bf8837e3d7ce 48069:3d0a9c6e614d
     1 use std::path::PathBuf;
       
     2 
       
     3 use crate::dirstate::parsers::Timestamp;
       
     4 use crate::dirstate::CopyMapIter;
       
     5 use crate::dirstate::StateMapIter;
       
     6 use crate::dirstate_tree::on_disk::DirstateV2ParseError;
       
     7 use crate::matchers::Matcher;
       
     8 use crate::utils::hg_path::{HgPath, HgPathBuf};
       
     9 use crate::DirstateEntry;
       
    10 use crate::DirstateError;
       
    11 use crate::DirstateParents;
       
    12 use crate::DirstateStatus;
       
    13 use crate::PatternFileWarning;
       
    14 use crate::StatusError;
       
    15 use crate::StatusOptions;
       
    16 
       
    17 /// `rust/hg-cpython/src/dirstate/dirstate_map.rs` implements in Rust a
       
    18 /// `DirstateMap` Python class that wraps `Box<dyn DirstateMapMethods + Send>`,
       
    19 /// a trait object of this trait. Except for constructors, this trait defines
       
    20 /// all APIs that the class needs to interact with its inner dirstate map.
       
    21 ///
       
    22 /// A trait object is used to support two different concrete types:
       
    23 ///
       
    24 /// * `rust/hg-core/src/dirstate/dirstate_map.rs` defines the "flat dirstate
       
    25 ///   map" which is based on a few large `HgPath`-keyed `HashMap` and `HashSet`
       
    26 ///   fields.
       
    27 /// * `rust/hg-core/src/dirstate_tree/dirstate_map.rs` defines the "tree
       
    28 ///   dirstate map" based on a tree data struture with nodes for directories
       
    29 ///   containing child nodes for their files and sub-directories. This tree
       
    30 ///   enables a more efficient algorithm for `hg status`, but its details are
       
    31 ///   abstracted in this trait.
       
    32 ///
       
    33 /// The dirstate map associates paths of files in the working directory to
       
    34 /// various information about the state of those files.
       
    35 pub trait DirstateMapMethods {
       
    36     /// Remove information about all files in this map
       
    37     fn clear(&mut self);
       
    38 
       
    39     /// Add the given filename to the map if it is not already there, and
       
    40     /// associate the given entry with it.
       
    41     fn set_entry(
       
    42         &mut self,
       
    43         filename: &HgPath,
       
    44         entry: DirstateEntry,
       
    45     ) -> Result<(), DirstateV2ParseError>;
       
    46 
       
    47     /// Add or change the information associated to a given file.
       
    48     fn add_file(
       
    49         &mut self,
       
    50         filename: &HgPath,
       
    51         entry: DirstateEntry,
       
    52     ) -> Result<(), DirstateError>;
       
    53 
       
    54     /// Mark a file as "removed" (as in `hg rm`).
       
    55     fn remove_file(
       
    56         &mut self,
       
    57         filename: &HgPath,
       
    58         in_merge: bool,
       
    59     ) -> Result<(), DirstateError>;
       
    60 
       
    61     /// Drop information about this file from the map if any.
       
    62     ///
       
    63     /// `get` will now return `None` for this filename.
       
    64     fn drop_entry_and_copy_source(
       
    65         &mut self,
       
    66         filename: &HgPath,
       
    67     ) -> Result<(), DirstateError>;
       
    68 
       
    69     /// Returns whether the sub-tree rooted at the given directory contains any
       
    70     /// tracked file.
       
    71     ///
       
    72     /// A file is tracked if it has a `state` other than `EntryState::Removed`.
       
    73     fn has_tracked_dir(
       
    74         &mut self,
       
    75         directory: &HgPath,
       
    76     ) -> Result<bool, DirstateError>;
       
    77 
       
    78     /// Returns whether the sub-tree rooted at the given directory contains any
       
    79     /// file with a dirstate entry.
       
    80     fn has_dir(&mut self, directory: &HgPath) -> Result<bool, DirstateError>;
       
    81 
       
    82     /// Clear mtimes equal to `now` in entries with `state ==
       
    83     /// EntryState::Normal`, and serialize bytes to write the `.hg/dirstate`
       
    84     /// file to disk in dirstate-v1 format.
       
    85     fn pack_v1(
       
    86         &mut self,
       
    87         parents: DirstateParents,
       
    88         now: Timestamp,
       
    89     ) -> Result<Vec<u8>, DirstateError>;
       
    90 
       
    91     /// Clear mtimes equal to `now` in entries with `state ==
       
    92     /// EntryState::Normal`, and serialize  bytes to write a dirstate data file
       
    93     /// to disk in dirstate-v2 format.
       
    94     ///
       
    95     /// Returns new data and metadata together with whether that data should be
       
    96     /// appended to the existing data file whose content is at
       
    97     /// `self.on_disk` (true), instead of written to a new data file
       
    98     /// (false).
       
    99     ///
       
   100     /// Note: this is only supported by the tree dirstate map.
       
   101     fn pack_v2(
       
   102         &mut self,
       
   103         now: Timestamp,
       
   104         can_append: bool,
       
   105     ) -> Result<(Vec<u8>, Vec<u8>, bool), DirstateError>;
       
   106 
       
   107     /// Run the status algorithm.
       
   108     ///
       
   109     /// This is not sematically a method of the dirstate map, but a different
       
   110     /// algorithm is used for the flat v.s. tree dirstate map so having it in
       
   111     /// this trait enables the same dynamic dispatch as with other methods.
       
   112     fn status<'a>(
       
   113         &'a mut self,
       
   114         matcher: &'a (dyn Matcher + Sync),
       
   115         root_dir: PathBuf,
       
   116         ignore_files: Vec<PathBuf>,
       
   117         options: StatusOptions,
       
   118     ) -> Result<(DirstateStatus<'a>, Vec<PatternFileWarning>), StatusError>;
       
   119 
       
   120     /// Returns how many files in the dirstate map have a recorded copy source.
       
   121     fn copy_map_len(&self) -> usize;
       
   122 
       
   123     /// Returns an iterator of `(path, copy_source)` for all files that have a
       
   124     /// copy source.
       
   125     fn copy_map_iter(&self) -> CopyMapIter<'_>;
       
   126 
       
   127     /// Returns whether the givef file has a copy source.
       
   128     fn copy_map_contains_key(
       
   129         &self,
       
   130         key: &HgPath,
       
   131     ) -> Result<bool, DirstateV2ParseError>;
       
   132 
       
   133     /// Returns the copy source for the given file.
       
   134     fn copy_map_get(
       
   135         &self,
       
   136         key: &HgPath,
       
   137     ) -> Result<Option<&HgPath>, DirstateV2ParseError>;
       
   138 
       
   139     /// Removes the recorded copy source if any for the given file, and returns
       
   140     /// it.
       
   141     fn copy_map_remove(
       
   142         &mut self,
       
   143         key: &HgPath,
       
   144     ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>;
       
   145 
       
   146     /// Set the given `value` copy source for the given `key` file.
       
   147     fn copy_map_insert(
       
   148         &mut self,
       
   149         key: HgPathBuf,
       
   150         value: HgPathBuf,
       
   151     ) -> Result<Option<HgPathBuf>, DirstateV2ParseError>;
       
   152 
       
   153     /// Returns the number of files that have an entry.
       
   154     fn len(&self) -> usize;
       
   155 
       
   156     /// Returns whether the given file has an entry.
       
   157     fn contains_key(&self, key: &HgPath)
       
   158         -> Result<bool, DirstateV2ParseError>;
       
   159 
       
   160     /// Returns the entry, if any, for the given file.
       
   161     fn get(
       
   162         &self,
       
   163         key: &HgPath,
       
   164     ) -> Result<Option<DirstateEntry>, DirstateV2ParseError>;
       
   165 
       
   166     /// Returns a `(path, entry)` iterator of files that have an entry.
       
   167     ///
       
   168     /// Because parse errors can happen during iteration, the iterated items
       
   169     /// are `Result`s.
       
   170     fn iter(&self) -> StateMapIter<'_>;
       
   171 
       
   172     /// Returns an iterator of tracked directories.
       
   173     ///
       
   174     /// This is the paths for which `has_tracked_dir` would return true.
       
   175     /// Or, in other words, the union of ancestor paths of all paths that have
       
   176     /// an associated entry in a "tracked" state in this dirstate map.
       
   177     ///
       
   178     /// Because parse errors can happen during iteration, the iterated items
       
   179     /// are `Result`s.
       
   180     fn iter_tracked_dirs(
       
   181         &mut self,
       
   182     ) -> Result<
       
   183         Box<
       
   184             dyn Iterator<Item = Result<&HgPath, DirstateV2ParseError>>
       
   185                 + Send
       
   186                 + '_,
       
   187         >,
       
   188         DirstateError,
       
   189     >;
       
   190 
       
   191     /// Return an iterator of `(path, (state, mode, size, mtime))` for every
       
   192     /// node stored in this dirstate map, for the purpose of the `hg
       
   193     /// debugdirstate` command.
       
   194     ///
       
   195     /// If `all` is true, include  nodes that don’t have an entry.
       
   196     /// For such nodes `state` is the ASCII space.
       
   197     /// An `mtime` may still be present. It is used to optimize `status`.
       
   198     ///
       
   199     /// Because parse errors can happen during iteration, the iterated items
       
   200     /// are `Result`s.
       
   201     fn debug_iter(
       
   202         &self,
       
   203         all: bool,
       
   204     ) -> Box<
       
   205         dyn Iterator<
       
   206                 Item = Result<
       
   207                     (&HgPath, (u8, i32, i32, i32)),
       
   208                     DirstateV2ParseError,
       
   209                 >,
       
   210             > + Send
       
   211             + '_,
       
   212     >;
       
   213 }