Mercurial > hg
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: "); |