From 8860d8de8d866192e1b2b867d54d8d9982299ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20N=2E=20Robalino?= Date: Sun, 3 Nov 2019 06:30:32 -0500 Subject: [PATCH] At the moment, ColumnPaths represent a set of Members (eg. package.authors is a column path of two members) The functions for retrieving, replacing, and inserting values into values all assumed they get the complete column path as regular tagged strings. This commit changes for these to accept a tagged values instead. Basically it means we can have column paths containing strings and numbers (eg. package.authors.1) Unfortunately, for the moment all members when parsed and deserialized for a command that expects column paths of tagged values will get tagged values (encapsulating Members) as strings only. This makes it impossible to determine whether package.authors.1 package.authors."1" (meaning the "number" 1) is a string member or a number member and thus prevents to know and force the user that paths enclosed in double quotes means "retrieve the column at this given table" and that numbers are for retrieving a particular row number from a table. This commit sets in place the infraestructure needed when integer members land, in the mean time the workaround is to convert back to strings the tagged values passed from the column paths. --- src/data/base.rs | 67 ++++--------------- .../hir/syntax_shape/expression/number.rs | 3 +- src/plugins/str.rs | 11 +-- 3 files changed, 18 insertions(+), 63 deletions(-) diff --git a/src/data/base.rs b/src/data/base.rs index 7d311a9949..72c98f2c89 100644 --- a/src/data/base.rs +++ b/src/data/base.rs @@ -558,59 +558,6 @@ impl Value { Ok(Some(current.tagged(tag))) } - pub fn insert_data_at_path( - &self, - tag: Tag, - path: &str, - new_value: Value, - ) -> Option> { - let mut new_obj = self.clone(); - - let split_path: Vec<_> = path.split(".").collect(); - - if let Value::Row(ref mut o) = new_obj { - let mut current = o; - - if split_path.len() == 1 { - // Special case for inserting at the top level - current - .entries - .insert(path.to_string(), new_value.tagged(&tag)); - return Some(new_obj.tagged(&tag)); - } - - for idx in 0..split_path.len() { - match current.entries.get_mut(split_path[idx]) { - Some(next) => { - if idx == (split_path.len() - 2) { - match &mut next.item { - Value::Row(o) => { - o.entries.insert( - split_path[idx + 1].to_string(), - new_value.tagged(&tag), - ); - } - _ => {} - } - - return Some(new_obj.tagged(&tag)); - } else { - match next.item { - Value::Row(ref mut o) => { - current = o; - } - _ => return None, - } - } - } - _ => return None, - } - } - } - - None - } - pub fn insert_data_at_column_path( &self, tag: Tag, @@ -680,11 +627,23 @@ impl Value { split_path: &Vec>, replaced_value: Value, ) -> Option> { + let split_path = split_path + .into_iter() + .map(|p| match p { + Tagged { + item: Value::Primitive(Primitive::String(s)), + tag, + } => Ok(s.clone().tagged(tag)), + o => Err(o), + }) + .filter_map(Result::ok) + .collect::>>(); + let mut new_obj = self.clone(); let mut current = &mut new_obj; for idx in 0..split_path.len() { - match current.get_mut_data_by_key(&split_path[idx].as_string().unwrap()) { + match current.get_mut_data_by_key(&split_path[idx].item) { Some(next) => { if idx == (split_path.len() - 1) { *next = replaced_value.tagged(&tag); diff --git a/src/parser/hir/syntax_shape/expression/number.rs b/src/parser/hir/syntax_shape/expression/number.rs index 9a7a6227dd..492a29202b 100644 --- a/src/parser/hir/syntax_shape/expression/number.rs +++ b/src/parser/hir/syntax_shape/expression/number.rs @@ -1,6 +1,7 @@ use crate::parser::hir::syntax_shape::{ expand_atom, parse_single_node, ExpandContext, ExpandExpression, ExpansionRule, - FallibleColorSyntax, FlatShape, TestSyntax, ParseError}; + FallibleColorSyntax, FlatShape, ParseError, TestSyntax, +}; use crate::parser::hir::tokens_iterator::Peeked; use crate::parser::{ hir, diff --git a/src/plugins/str.rs b/src/plugins/str.rs index 552602acc0..5741897fd4 100644 --- a/src/plugins/str.rs +++ b/src/plugins/str.rs @@ -249,14 +249,9 @@ impl Plugin for Str { string @ Tagged { item: Value::Primitive(Primitive::String(_)), .. - } => match self.action { - Some(Action::Downcase) - | Some(Action::Upcase) - | Some(Action::ToInteger) - | None => { - self.for_field(string.as_column_path()?); - } - }, + } => { + self.for_field(string.as_column_path()?); + } table @ Tagged { item: Value::Table(_), ..