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 } |
|