From d1b1438ce5cfdec1eef7565c9a8db4cd0c429d6f Mon Sep 17 00:00:00 2001 From: John Erickson Date: Sun, 17 May 2020 11:52:17 -0700 Subject: [PATCH] Check capture group count (#1814) --- crates/nu_plugin_parse/src/nu/mod.rs | 37 ++++++++++++++++++++++++++-- crates/nu_plugin_parse/src/parse.rs | 2 ++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/crates/nu_plugin_parse/src/nu/mod.rs b/crates/nu_plugin_parse/src/nu/mod.rs index bc6a1b781..7e0aae0b2 100644 --- a/crates/nu_plugin_parse/src/nu/mod.rs +++ b/crates/nu_plugin_parse/src/nu/mod.rs @@ -26,6 +26,7 @@ impl Plugin for Parse { value: UntaggedValue::Primitive(Primitive::String(s)), tag, } => { + self.pattern_tag = tag.clone(); let parse_pattern = parse(&s); let parse_regex = build_regex(&parse_pattern); self.column_names = column_names(&parse_pattern); @@ -54,12 +55,44 @@ impl Plugin for Parse { match &input.as_string() { Ok(s) => { let mut output = vec![]; - for cap in self.regex.captures_iter(&s) { + for caps in self.regex.captures_iter(&s) { + let group_count = caps.len() - 1; + + if self.column_names.len() != group_count { + return Err(ShellError::labeled_error( + format!( + "There are {} column(s) specified in the pattern, but could only match the first {}: [{}]", + self.column_names.len(), + group_count, + caps.iter() + .skip(1) + .map(|m| { + if let Some(m) = m { + let m = m.as_str(); + let mut m = m.replace(",","\\,"); + if m.len() > 20 { + m.truncate(17); + format!("{}...", m) + } else { + m + } + } else { + "".to_string() + } + }) + .collect::>() + .join(", ") + ), + "could not match all columns in pattern", + &self.pattern_tag, + )); + } + let mut dict = TaggedDictBuilder::new(&input.tag); for (idx, column_name) in self.column_names.iter().enumerate() { dict.insert_untagged( column_name, - UntaggedValue::string(cap[idx + 1].to_string()), + UntaggedValue::string(caps[idx + 1].to_string()), ); } output.push(Ok(ReturnSuccess::Value(dict.into_value()))); diff --git a/crates/nu_plugin_parse/src/parse.rs b/crates/nu_plugin_parse/src/parse.rs index 82d1b090a..ba8263244 100644 --- a/crates/nu_plugin_parse/src/parse.rs +++ b/crates/nu_plugin_parse/src/parse.rs @@ -4,6 +4,7 @@ use regex::Regex; pub struct Parse { pub regex: Regex, pub name: Tag, + pub pattern_tag: Tag, pub column_names: Vec, } @@ -13,6 +14,7 @@ impl Parse { Ok(Parse { regex: Regex::new("")?, name: Tag::unknown(), + pattern_tag: Tag::unknown(), column_names: vec![], }) }