From 1bbc4a9ecda576d714d0e0735b965982adad1fbb Mon Sep 17 00:00:00 2001 From: Ferran Basora Date: Thu, 21 Feb 2019 14:03:24 +0000 Subject: [PATCH] Add support for patterns with groups (diff) --- src/state.rs | 61 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/state.rs b/src/state.rs index dc15312..db1fa4a 100644 --- a/src/state.rs +++ b/src/state.rs @@ -34,6 +34,8 @@ impl<'a> State<'a> { let mut patterns = Vec::new(); patterns.push(Regex::new(r"((https?://|git@|git://|ssh://|ftp://|file:///)[\w?=%/_.:,;~@!#$&()*+-]*)").unwrap()); // Urls + patterns.push(Regex::new(r"--- a/([^ ]+)").unwrap()); // Diff + patterns.push(Regex::new(r"\+\+\+ b/([^ ]+)").unwrap()); // Diff patterns.push(Regex::new(r"[^ ]+/[^ ]+").unwrap()); // Paths patterns.push(Regex::new(r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}").unwrap()); // Uid patterns.push(Regex::new(r"[0-9a-f]{7,40}").unwrap()); // Sha id @@ -46,19 +48,38 @@ impl<'a> State<'a> { let mut offset: i32 = 0; loop { - let submatches = patterns.iter().filter_map(|pattern| pattern.find_iter(chunk).nth(0)).collect::>(); - let first_match_option = submatches.iter().min_by(|x, y| x.start().cmp(&y.start())); + let submatches = patterns.iter().filter_map(|pattern| + match pattern.find_iter(chunk).nth(0) { + Some(m) => Some((pattern, m)), + None => None + } + ).collect::>(); + let first_match_option = submatches.iter().min_by(|x, y| x.1.start().cmp(&y.1.start())); if let Some(first_match) = first_match_option { - matches.push(Match{ - x: offset + first_match.start() as i32, - y: index as i32, - text: &chunk[first_match.start()..first_match.end()], - hint: None - }); + let (pattern, matching) = first_match; + let text = &chunk[matching.start()..matching.end()]; // FIXME? matching.as_str() - chunk = chunk.get(first_match.end()..).expect("Unknown chunk"); - offset = offset + first_match.end() as i32; + if let Some(captures) = pattern.captures(text) { + let (subtext, substart) = if let Some(capture) = captures.get(1) { + (capture.as_str(), capture.start()) + } else { + (matching.as_str(), 0) + }; + + matches.push(Match{ + x: offset + matching.start() as i32 + substart as i32, + y: index as i32, + text: subtext, + hint: None + }); + + chunk = chunk.get(matching.end()..).expect("Unknown chunk"); + offset = offset + matching.end() as i32; + + } else { + panic!("No matching?"); + } } else { break; } @@ -199,6 +220,26 @@ mod tests { assert_eq!(match_lines(output).len(), 8); } + #[test] + fn match_diff_a () { + let output = "Lorem lorem\n--- a/src/main.rs"; + + let results = match_lines(output); + + assert_eq!(results.len(), 1); + assert_eq!(results.first().unwrap().text.clone(), "src/main.rs"); + } + + #[test] + fn match_diff_b () { + let output = "Lorem lorem\n+++ b/src/main.rs"; + + let results = match_lines(output); + + assert_eq!(results.len(), 1); + assert_eq!(results.first().unwrap().text.clone(), "src/main.rs"); + } + #[test] fn priority () { let output = "Lorem /var/fd70b569/9999.log 52463 lorem\n Lorem 973113 lorem 123e4567-e89b-12d3-a456-426655440000 lorem 8888 lorem\n https://crates.io/23456/fd70b569 lorem";