From a2d074d0758e2a152de9647ce54658112c41b7d9 Mon Sep 17 00:00:00 2001 From: Steve Donovan Date: Thu, 20 Apr 2017 16:19:14 +0200 Subject: [PATCH] matches_maybe and first_closure --- src/lib.rs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 45d8240..6b0ac67 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -119,6 +119,21 @@ impl <'a> LuaPattern<'a> { self.matches_bytes(text.as_bytes()) } + /// Match a string, returning first capture if successful + /// + /// ``` + /// let mut m = lua_patterns::LuaPattern::new("OK%s+(%d+)"); + /// let res = m.match_maybe("and that's OK 400 to you"); + /// assert_eq!(res, Some("400")); + /// ``` + pub fn match_maybe<'t>(&mut self, text: &'t str) -> Option<&'t str> { + if self.matches(text) { + Some(&text[self.first_capture()]) + } else { + None + } + } + /// Match and collect all captures as a vector of string slices /// /// ``` @@ -186,6 +201,15 @@ impl <'a> LuaPattern<'a> { } } + /// Get the 'first' capture of the match + /// + /// If there are no matches, this is the same as `range`, + /// otherwise it's `capture(1)` + pub fn first_capture(&self) -> ops::Range { + let idx = if self.n_match > 1 {1} else {0}; + self.capture(idx) + } + /// An iterator over all matches in a string. /// /// The matches are returned as string slices; if there are no @@ -418,8 +442,7 @@ impl <'a,'b>Iterator for GMatch<'a,'b> { if ! self.m.matches(self.text) { None } else { - let first = if self.m.n_match > 1 {1} else {0}; - let slice = &self.text[self.m.capture(first)]; + let slice = &self.text[self.m.first_capture()]; self.text = &self.text[self.m.range().end..]; Some(slice) } @@ -440,8 +463,7 @@ impl <'a,'b>Iterator for GMatchBytes<'a,'b> { if ! self.m.matches_bytes(self.bytes) { None } else { - let first = if self.m.n_match > 1 {1} else {0}; - let slice = &self.bytes[self.m.capture(first)]; + let slice = &self.bytes[self.m.first_capture()]; self.bytes = &self.bytes[self.m.range().end..]; Some(slice) } @@ -473,6 +495,33 @@ impl LuaPatternBuilder { self } + /// Add unescaped characters from lines + /// + /// This looks for first non-whitespace run in each line, + /// useful for spreading patterns out and commmenting them. + /// Works with patterns that use '%s' religiously! + /// + /// ``` + /// let patt = lua_patterns::LuaPatternBuilder::new() + /// .text_lines(" + /// hello-dolly + /// you-are-fine # comment + /// cool + /// ") + /// .build(); + /// assert_eq!(std::str::from_utf8(&patt).unwrap(), + /// "hello-dollyyou-are-finecool"); + /// ``` + pub fn text_lines(&mut self, lines: &str) -> &mut Self { + let mut text = String::new(); + for line in lines.lines() { + if let Some(first) = line.split_whitespace().next() { + text.push_str(first); + } + } + self.text(&text) + } + /// Add escaped bytes from a slice /// /// ```