Show More
@@ -30,7 +30,7 b' impl DirsMultiset {' | |||
|
30 | 30 | pub fn from_dirstate( |
|
31 | 31 | dirstate: &FastHashMap<HgPathBuf, DirstateEntry>, |
|
32 | 32 | skip_state: Option<EntryState>, |
|
33 | ) -> Self { | |
|
33 | ) -> Result<Self, DirstateMapError> { | |
|
34 | 34 | let mut multiset = DirsMultiset { |
|
35 | 35 | inner: FastHashMap::default(), |
|
36 | 36 | }; |
@@ -39,27 +39,29 b' impl DirsMultiset {' | |||
|
39 | 39 | // This `if` is optimized out of the loop |
|
40 | 40 | if let Some(skip) = skip_state { |
|
41 | 41 | if skip != *state { |
|
42 | multiset.add_path(filename); | |
|
42 | multiset.add_path(filename)?; | |
|
43 | 43 | } |
|
44 | 44 | } else { |
|
45 | multiset.add_path(filename); | |
|
45 | multiset.add_path(filename)?; | |
|
46 | 46 | } |
|
47 | 47 | } |
|
48 | 48 | |
|
49 | multiset | |
|
49 | Ok(multiset) | |
|
50 | 50 | } |
|
51 | 51 | |
|
52 | 52 | /// Initializes the multiset from a manifest. |
|
53 | pub fn from_manifest(manifest: &[impl AsRef<HgPath>]) -> Self { | |
|
53 | pub fn from_manifest( | |
|
54 | manifest: &[impl AsRef<HgPath>], | |
|
55 | ) -> Result<Self, DirstateMapError> { | |
|
54 | 56 | let mut multiset = DirsMultiset { |
|
55 | 57 | inner: FastHashMap::default(), |
|
56 | 58 | }; |
|
57 | 59 | |
|
58 | 60 | for filename in manifest { |
|
59 | multiset.add_path(filename.as_ref()); | |
|
61 | multiset.add_path(filename.as_ref())?; | |
|
60 | 62 | } |
|
61 | 63 | |
|
62 | multiset | |
|
64 | Ok(multiset) | |
|
63 | 65 | } |
|
64 | 66 | |
|
65 | 67 | /// Increases the count of deepest directory contained in the path. |
@@ -134,7 +136,7 b' mod tests {' | |||
|
134 | 136 | #[test] |
|
135 | 137 | fn test_delete_path_path_not_found() { |
|
136 | 138 | let manifest: Vec<HgPathBuf> = vec![]; |
|
137 | let mut map = DirsMultiset::from_manifest(&manifest); | |
|
139 | let mut map = DirsMultiset::from_manifest(&manifest).unwrap(); | |
|
138 | 140 | let path = HgPathBuf::from_bytes(b"doesnotexist/"); |
|
139 | 141 | assert_eq!( |
|
140 | 142 | Err(DirstateMapError::PathNotFound(path.to_owned())), |
@@ -144,7 +146,8 b' mod tests {' | |||
|
144 | 146 | |
|
145 | 147 | #[test] |
|
146 | 148 | fn test_delete_path_empty_path() { |
|
147 | let mut map = DirsMultiset::from_manifest(&vec![HgPathBuf::new()]); | |
|
149 | let mut map = | |
|
150 | DirsMultiset::from_manifest(&vec![HgPathBuf::new()]).unwrap(); | |
|
148 | 151 | let path = HgPath::new(b""); |
|
149 | 152 | assert_eq!(Ok(()), map.delete_path(path)); |
|
150 | 153 | assert_eq!( |
@@ -191,7 +194,7 b' mod tests {' | |||
|
191 | 194 | #[test] |
|
192 | 195 | fn test_add_path_empty_path() { |
|
193 | 196 | let manifest: Vec<HgPathBuf> = vec![]; |
|
194 | let mut map = DirsMultiset::from_manifest(&manifest); | |
|
197 | let mut map = DirsMultiset::from_manifest(&manifest).unwrap(); | |
|
195 | 198 | let path = HgPath::new(b""); |
|
196 | 199 | map.add_path(path); |
|
197 | 200 | |
@@ -201,7 +204,7 b' mod tests {' | |||
|
201 | 204 | #[test] |
|
202 | 205 | fn test_add_path_successful() { |
|
203 | 206 | let manifest: Vec<HgPathBuf> = vec![]; |
|
204 | let mut map = DirsMultiset::from_manifest(&manifest); | |
|
207 | let mut map = DirsMultiset::from_manifest(&manifest).unwrap(); | |
|
205 | 208 | |
|
206 | 209 | map.add_path(HgPath::new(b"a/")); |
|
207 | 210 | assert_eq!(1, *map.inner.get(HgPath::new(b"a")).unwrap()); |
@@ -247,13 +250,14 b' mod tests {' | |||
|
247 | 250 | #[test] |
|
248 | 251 | fn test_dirsmultiset_new_empty() { |
|
249 | 252 | let manifest: Vec<HgPathBuf> = vec![]; |
|
250 | let new = DirsMultiset::from_manifest(&manifest); | |
|
253 | let new = DirsMultiset::from_manifest(&manifest).unwrap(); | |
|
251 | 254 | let expected = DirsMultiset { |
|
252 | 255 | inner: FastHashMap::default(), |
|
253 | 256 | }; |
|
254 | 257 | assert_eq!(expected, new); |
|
255 | 258 | |
|
256 |
let new = DirsMultiset::from_dirstate(&FastHashMap::default(), None) |
|
|
259 | let new = DirsMultiset::from_dirstate(&FastHashMap::default(), None) | |
|
260 | .unwrap(); | |
|
257 | 261 | let expected = DirsMultiset { |
|
258 | 262 | inner: FastHashMap::default(), |
|
259 | 263 | }; |
@@ -271,7 +275,7 b' mod tests {' | |||
|
271 | 275 | .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
|
272 | 276 | .collect(); |
|
273 | 277 | |
|
274 | let new = DirsMultiset::from_manifest(&input_vec); | |
|
278 | let new = DirsMultiset::from_manifest(&input_vec).unwrap(); | |
|
275 | 279 | let expected = DirsMultiset { |
|
276 | 280 | inner: expected_inner, |
|
277 | 281 | }; |
@@ -296,7 +300,7 b' mod tests {' | |||
|
296 | 300 | .map(|(k, v)| (HgPathBuf::from_bytes(k.as_bytes()), *v)) |
|
297 | 301 | .collect(); |
|
298 | 302 | |
|
299 | let new = DirsMultiset::from_dirstate(&input_map, None); | |
|
303 | let new = DirsMultiset::from_dirstate(&input_map, None).unwrap(); | |
|
300 | 304 | let expected = DirsMultiset { |
|
301 | 305 | inner: expected_inner, |
|
302 | 306 | }; |
@@ -332,7 +336,8 b' mod tests {' | |||
|
332 | 336 | .collect(); |
|
333 | 337 | |
|
334 | 338 | let new = |
|
335 |
DirsMultiset::from_dirstate(&input_map, Some(EntryState::Normal)) |
|
|
339 | DirsMultiset::from_dirstate(&input_map, Some(EntryState::Normal)) | |
|
340 | .unwrap(); | |
|
336 | 341 | let expected = DirsMultiset { |
|
337 | 342 | inner: expected_inner, |
|
338 | 343 | }; |
@@ -126,7 +126,7 b' impl DirstateMap {' | |||
|
126 | 126 | } |
|
127 | 127 | if old_state == EntryState::Unknown { |
|
128 | 128 | if let Some(ref mut all_dirs) = self.all_dirs { |
|
129 | all_dirs.add_path(filename); | |
|
129 | all_dirs.add_path(filename)?; | |
|
130 | 130 | } |
|
131 | 131 | } |
|
132 | 132 | |
@@ -227,30 +227,38 b' impl DirstateMap {' | |||
|
227 | 227 | /// emulate a Python lazy property, but it is ugly and unidiomatic. |
|
228 | 228 | /// TODO One day, rewriting this struct using the typestate might be a |
|
229 | 229 | /// good idea. |
|
230 | pub fn set_all_dirs(&mut self) { | |
|
230 | pub fn set_all_dirs(&mut self) -> Result<(), DirstateMapError> { | |
|
231 | 231 | if self.all_dirs.is_none() { |
|
232 | 232 | self.all_dirs = |
|
233 | Some(DirsMultiset::from_dirstate(&self.state_map, None)); | |
|
233 | Some(DirsMultiset::from_dirstate(&self.state_map, None)?); | |
|
234 | 234 | } |
|
235 | Ok(()) | |
|
235 | 236 | } |
|
236 | 237 | |
|
237 | pub fn set_dirs(&mut self) { | |
|
238 | pub fn set_dirs(&mut self) -> Result<(), DirstateMapError> { | |
|
238 | 239 | if self.dirs.is_none() { |
|
239 | 240 | self.dirs = Some(DirsMultiset::from_dirstate( |
|
240 | 241 | &self.state_map, |
|
241 | 242 | Some(EntryState::Removed), |
|
242 | )); | |
|
243 | )?); | |
|
243 | 244 | } |
|
245 | Ok(()) | |
|
244 | 246 | } |
|
245 | 247 | |
|
246 | pub fn has_tracked_dir(&mut self, directory: &HgPath) -> bool { | |
|
247 | self.set_dirs(); | |
|
248 | self.dirs.as_ref().unwrap().contains(directory) | |
|
248 | pub fn has_tracked_dir( | |
|
249 | &mut self, | |
|
250 | directory: &HgPath, | |
|
251 | ) -> Result<bool, DirstateMapError> { | |
|
252 | self.set_dirs()?; | |
|
253 | Ok(self.dirs.as_ref().unwrap().contains(directory)) | |
|
249 | 254 | } |
|
250 | 255 | |
|
251 | pub fn has_dir(&mut self, directory: &HgPath) -> bool { | |
|
252 | self.set_all_dirs(); | |
|
253 | self.all_dirs.as_ref().unwrap().contains(directory) | |
|
256 | pub fn has_dir( | |
|
257 | &mut self, | |
|
258 | directory: &HgPath, | |
|
259 | ) -> Result<bool, DirstateMapError> { | |
|
260 | self.set_all_dirs()?; | |
|
261 | Ok(self.all_dirs.as_ref().unwrap().contains(directory)) | |
|
254 | 262 | } |
|
255 | 263 | |
|
256 | 264 | pub fn parents( |
@@ -350,11 +358,11 b' mod tests {' | |||
|
350 | 358 | assert!(map.dirs.is_none()); |
|
351 | 359 | assert!(map.all_dirs.is_none()); |
|
352 | 360 | |
|
353 |
assert_eq!( |
|
|
361 | assert_eq!(map.has_dir(HgPath::new(b"nope")).unwrap(), false); | |
|
354 | 362 | assert!(map.all_dirs.is_some()); |
|
355 | 363 | assert!(map.dirs.is_none()); |
|
356 | 364 | |
|
357 |
assert_eq!( |
|
|
365 | assert_eq!(map.has_tracked_dir(HgPath::new(b"nope")).unwrap(), false); | |
|
358 | 366 | assert!(map.dirs.is_some()); |
|
359 | 367 | } |
|
360 | 368 |
@@ -7,7 +7,7 b'' | |||
|
7 | 7 | |
|
8 | 8 | //! Structs and types for matching files and directories. |
|
9 | 9 | |
|
10 |
use crate::utils::hg_path:: |
|
|
10 | use crate::utils::hg_path::HgPath; | |
|
11 | 11 | use std::collections::HashSet; |
|
12 | 12 | |
|
13 | 13 | pub enum VisitChildrenSet<'a> { |
@@ -47,6 +47,9 b' py_class!(pub class Dirs |py| {' | |||
|
47 | 47 | let inner = if let Ok(map) = map.cast_as::<PyDict>(py) { |
|
48 | 48 | let dirstate = extract_dirstate(py, &map)?; |
|
49 | 49 | DirsMultiset::from_dirstate(&dirstate, skip_state) |
|
50 | .map_err(|e| { | |
|
51 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
52 | })? | |
|
50 | 53 | } else { |
|
51 | 54 | let map: Result<Vec<HgPathBuf>, PyErr> = map |
|
52 | 55 | .iter(py)? |
@@ -57,6 +60,9 b' py_class!(pub class Dirs |py| {' | |||
|
57 | 60 | }) |
|
58 | 61 | .collect(); |
|
59 | 62 | DirsMultiset::from_manifest(&map?) |
|
63 | .map_err(|e| { | |
|
64 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
65 | })? | |
|
60 | 66 | }; |
|
61 | 67 | |
|
62 | 68 | Self::create_instance( |
@@ -200,6 +200,9 b' py_class!(pub class DirstateMap |py| {' | |||
|
200 | 200 | let d = d.extract::<PyBytes>(py)?; |
|
201 | 201 | Ok(self.inner_shared(py).borrow_mut()? |
|
202 | 202 | .has_tracked_dir(HgPath::new(d.data(py))) |
|
203 | .map_err(|e| { | |
|
204 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
205 | })? | |
|
203 | 206 | .to_py_object(py)) |
|
204 | 207 | } |
|
205 | 208 | |
@@ -207,6 +210,9 b' py_class!(pub class DirstateMap |py| {' | |||
|
207 | 210 | let d = d.extract::<PyBytes>(py)?; |
|
208 | 211 | Ok(self.inner_shared(py).borrow_mut()? |
|
209 | 212 | .has_dir(HgPath::new(d.data(py))) |
|
213 | .map_err(|e| { | |
|
214 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
215 | })? | |
|
210 | 216 | .to_py_object(py)) |
|
211 | 217 | } |
|
212 | 218 | |
@@ -330,24 +336,35 b' py_class!(pub class DirstateMap |py| {' | |||
|
330 | 336 | |
|
331 | 337 | def getdirs(&self) -> PyResult<Dirs> { |
|
332 | 338 | // TODO don't copy, share the reference |
|
333 |
self.inner_shared(py).borrow_mut()?.set_dirs() |
|
|
339 | self.inner_shared(py).borrow_mut()?.set_dirs() | |
|
340 | .map_err(|e| { | |
|
341 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
342 | })?; | |
|
334 | 343 | Dirs::from_inner( |
|
335 | 344 | py, |
|
336 | 345 | DirsMultiset::from_dirstate( |
|
337 | 346 | &self.inner_shared(py).borrow(), |
|
338 | 347 | Some(EntryState::Removed), |
|
339 |
) |
|
|
348 | ) | |
|
349 | .map_err(|e| { | |
|
350 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
351 | })?, | |
|
340 | 352 | ) |
|
341 | 353 | } |
|
342 | 354 | def getalldirs(&self) -> PyResult<Dirs> { |
|
343 | 355 | // TODO don't copy, share the reference |
|
344 |
self.inner_shared(py).borrow_mut()?.set_all_dirs() |
|
|
356 | self.inner_shared(py).borrow_mut()?.set_all_dirs() | |
|
357 | .map_err(|e| { | |
|
358 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
359 | })?; | |
|
345 | 360 | Dirs::from_inner( |
|
346 | 361 | py, |
|
347 | 362 | DirsMultiset::from_dirstate( |
|
348 | 363 | &self.inner_shared(py).borrow(), |
|
349 | 364 | None, |
|
350 |
) |
|
|
365 | ).map_err(|e| { | |
|
366 | PyErr::new::<exc::ValueError, _>(py, e.to_string()) | |
|
367 | })?, | |
|
351 | 368 | ) |
|
352 | 369 | } |
|
353 | 370 |
General Comments 0
You need to be logged in to leave comments.
Login now