comparison rust/hg-core/src/matchers.rs @ 51274:bec6e9c108fd

matchers: use correct method for finding index in vector The path matcher has an optimization for when all paths are `rootfilesin:`. This optimization exists in both Python and Rust. However, the Rust implementation currently has a bug that makes it fail in most cases. The bug is that it `rfind()` where it was clearly intended to use `rposition()`. This patch fixes that and adds a test.
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 18 Dec 2023 14:51:20 -0800
parents 532e74ad3ff6
children 5633de951d34
comparison
equal deleted inserted replaced
51273:79cd29d598af 51274:bec6e9c108fd
386 /// /// 386 /// ///
387 /// assert_eq!(matcher.matches(HgPath::new(b"testing")), false); 387 /// assert_eq!(matcher.matches(HgPath::new(b"testing")), false);
388 /// assert_eq!(matcher.matches(HgPath::new(b"this should work")), true); 388 /// assert_eq!(matcher.matches(HgPath::new(b"this should work")), true);
389 /// assert_eq!(matcher.matches(HgPath::new(b"this also")), true); 389 /// assert_eq!(matcher.matches(HgPath::new(b"this also")), true);
390 /// assert_eq!(matcher.matches(HgPath::new(b"but not this")), false); 390 /// assert_eq!(matcher.matches(HgPath::new(b"but not this")), false);
391 /// ///
392 /// let ignore_patterns =
393 /// vec![IgnorePattern::new(PatternSyntax::RootFiles, b"dir/subdir", Path::new(""))];
394 /// let matcher = IncludeMatcher::new(ignore_patterns).unwrap();
395 /// ///
396 /// assert!(!matcher.matches(HgPath::new(b"file")));
397 /// assert!(!matcher.matches(HgPath::new(b"dir/file")));
398 /// assert!(matcher.matches(HgPath::new(b"dir/subdir/file")));
399 /// assert!(!matcher.matches(HgPath::new(b"dir/subdir/subsubdir/file")));
391 /// ``` 400 /// ```
392 pub struct IncludeMatcher<'a> { 401 pub struct IncludeMatcher<'a> {
393 patterns: Vec<u8>, 402 patterns: Vec<u8>,
394 match_fn: IgnoreFnType<'a>, 403 match_fn: IgnoreFnType<'a>,
395 /// Whether all the patterns match a prefix (i.e. recursively) 404 /// Whether all the patterns match a prefix (i.e. recursively)
949 .collect(); 958 .collect();
950 let mut dirs_vec: Vec<_> = dirs.iter().cloned().collect(); 959 let mut dirs_vec: Vec<_> = dirs.iter().cloned().collect();
951 960
952 let match_func = move |path: &HgPath| -> bool { 961 let match_func = move |path: &HgPath| -> bool {
953 let path = path.as_bytes(); 962 let path = path.as_bytes();
954 let i = path.iter().rfind(|a| **a == b'/'); 963 let i = path.iter().rposition(|a| *a == b'/');
955 let dir = if let Some(i) = i { 964 let dir = if let Some(i) = i { &path[..i] } else { b"." };
956 &path[..*i as usize]
957 } else {
958 b"."
959 };
960 dirs.contains(dir) 965 dirs.contains(dir)
961 }; 966 };
962 match_funcs.push(Box::new(match_func)); 967 match_funcs.push(Box::new(match_func));
963 968
964 patterns.extend(b"rootfilesin: "); 969 patterns.extend(b"rootfilesin: ");