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 //! A multiset of directory names. |
8 //! A multiset of directory names. |
9 //! |
9 //! |
10 //! Used to counts the references to directories in a manifest or dirstate. |
10 //! Used to counts the references to directories in a manifest or dirstate. |
11 use crate::{utils::files, DirsIterable, DirstateEntry, DirstateMapError}; |
11 use crate::{ |
|
12 dirstate::EntryState, utils::files, DirsIterable, DirstateEntry, |
|
13 DirstateMapError, |
|
14 }; |
12 use std::collections::hash_map::{Entry, Iter}; |
15 use std::collections::hash_map::{Entry, Iter}; |
13 use std::collections::HashMap; |
16 use std::collections::HashMap; |
14 |
17 |
15 #[derive(PartialEq, Debug)] |
18 #[derive(PartialEq, Debug)] |
16 pub struct DirsMultiset { |
19 pub struct DirsMultiset { |
19 |
22 |
20 impl DirsMultiset { |
23 impl DirsMultiset { |
21 /// Initializes the multiset from a dirstate or a manifest. |
24 /// Initializes the multiset from a dirstate or a manifest. |
22 /// |
25 /// |
23 /// If `skip_state` is provided, skips dirstate entries with equal state. |
26 /// If `skip_state` is provided, skips dirstate entries with equal state. |
24 pub fn new(iterable: DirsIterable, skip_state: Option<i8>) -> Self { |
27 pub fn new( |
|
28 iterable: DirsIterable, |
|
29 skip_state: Option<EntryState>, |
|
30 ) -> Self { |
25 let mut multiset = DirsMultiset { |
31 let mut multiset = DirsMultiset { |
26 inner: HashMap::new(), |
32 inner: HashMap::new(), |
27 }; |
33 }; |
28 |
34 |
29 match iterable { |
35 match iterable { |
288 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)] |
294 let expected_inner = [("", 2), ("a", 3), ("b", 1), ("a/d", 1)] |
289 .iter() |
295 .iter() |
290 .map(|(k, v)| (k.as_bytes().to_vec(), *v)) |
296 .map(|(k, v)| (k.as_bytes().to_vec(), *v)) |
291 .collect(); |
297 .collect(); |
292 |
298 |
293 let new = DirsMultiset::new(Manifest(&input_vec), Some('n' as i8)); |
299 let new = |
|
300 DirsMultiset::new(Manifest(&input_vec), Some(EntryState::Normal)); |
294 let expected = DirsMultiset { |
301 let expected = DirsMultiset { |
295 inner: expected_inner, |
302 inner: expected_inner, |
296 }; |
303 }; |
297 // Skip does not affect a manifest |
304 // Skip does not affect a manifest |
298 assert_eq!(expected, new); |
305 assert_eq!(expected, new); |
299 |
306 |
300 let input_map = |
307 let input_map = [ |
301 [("a/", 'n'), ("a/b/", 'n'), ("a/c", 'r'), ("a/d/", 'm')] |
308 ("a/", EntryState::Normal), |
302 .iter() |
309 ("a/b/", EntryState::Normal), |
303 .map(|(f, state)| { |
310 ("a/c", EntryState::Removed), |
304 ( |
311 ("a/d/", EntryState::Merged), |
305 f.as_bytes().to_vec(), |
312 ] |
306 DirstateEntry { |
313 .iter() |
307 state: *state as i8, |
314 .map(|(f, state)| { |
308 mode: 0, |
315 ( |
309 mtime: 0, |
316 f.as_bytes().to_vec(), |
310 size: 0, |
317 DirstateEntry { |
311 }, |
318 state: *state, |
312 ) |
319 mode: 0, |
313 }) |
320 mtime: 0, |
314 .collect(); |
321 size: 0, |
|
322 }, |
|
323 ) |
|
324 }) |
|
325 .collect(); |
315 |
326 |
316 // "a" incremented with "a/c" and "a/d/" |
327 // "a" incremented with "a/c" and "a/d/" |
317 let expected_inner = [("", 1), ("a", 2), ("a/d", 1)] |
328 let expected_inner = [("", 1), ("a", 2), ("a/d", 1)] |
318 .iter() |
329 .iter() |
319 .map(|(k, v)| (k.as_bytes().to_vec(), *v)) |
330 .map(|(k, v)| (k.as_bytes().to_vec(), *v)) |
320 .collect(); |
331 .collect(); |
321 |
332 |
322 let new = DirsMultiset::new(Dirstate(&input_map), Some('n' as i8)); |
333 let new = |
|
334 DirsMultiset::new(Dirstate(&input_map), Some(EntryState::Normal)); |
323 let expected = DirsMultiset { |
335 let expected = DirsMultiset { |
324 inner: expected_inner, |
336 inner: expected_inner, |
325 }; |
337 }; |
326 assert_eq!(expected, new); |
338 assert_eq!(expected, new); |
327 } |
339 } |
|
340 |
328 } |
341 } |