Move column paths to support broader value types.

This commit is contained in:
Andrés N. Robalino
2019-11-01 16:19:46 -05:00
parent 1b784cb77a
commit 6ea8e42331
13 changed files with 201 additions and 123 deletions

View File

@ -3,7 +3,7 @@ use nu::{
Tagged, Value,
};
pub type ColumnPath = Tagged<Vec<Tagged<String>>>;
pub type ColumnPath = Tagged<Vec<Tagged<Value>>>;
struct Edit {
field: Option<ColumnPath>,

View File

@ -14,7 +14,7 @@ pub enum SemVerAction {
Patch,
}
pub type ColumnPath = Vec<Tagged<String>>;
pub type ColumnPath = Tagged<Vec<Tagged<Value>>>;
struct Inc {
field: Option<ColumnPath>,
@ -100,7 +100,7 @@ impl Inc {
let replace_for = value.item.get_data_by_column_path(
value.tag(),
&f,
f,
Box::new(move |(obj_source, column_path_tried)| {
match did_you_mean(&obj_source, &column_path_tried) {
Some(suggestions) => {
@ -191,7 +191,7 @@ impl Plugin for Inc {
item: Value::Table(_),
..
} => {
self.field = Some(table.as_column_path()?.item().to_vec());
self.field = Some(table.as_column_path()?);
}
value => return Err(ShellError::type_error("table", value.tagged_type_name())),
}
@ -229,8 +229,8 @@ mod tests {
use super::{Inc, SemVerAction};
use indexmap::IndexMap;
use nu::{
CallInfo, EvaluatedArgs, Plugin, ReturnSuccess, Tag, Tagged, TaggedDictBuilder, TaggedItem,
Value,
CallInfo, EvaluatedArgs, Plugin, Primitive, ReturnSuccess, Tag, Tagged, TaggedDictBuilder,
TaggedItem, Value,
};
struct CallStub {
@ -344,9 +344,13 @@ mod tests {
.is_ok());
assert_eq!(
plugin
.field
.map(|f| f.iter().map(|f| f.item.clone()).collect()),
plugin.field.map(|f| f
.iter()
.map(|f| match &f.item {
Value::Primitive(Primitive::String(s)) => s.clone(),
_ => panic!(""),
})
.collect()),
Some(vec!["package".to_string(), "version".to_string()])
);
}

View File

@ -4,7 +4,7 @@ use nu::{
Tagged, TaggedItem, Value,
};
pub type ColumnPath = Vec<Tagged<String>>;
pub type ColumnPath = Vec<Tagged<Value>>;
struct Insert {
field: Option<ColumnPath>,
@ -22,14 +22,21 @@ impl Insert {
let value_tag = value.tag();
match (value.item, self.value.clone()) {
(obj @ Value::Row(_), Some(v)) => match &self.field {
Some(f) => match obj.insert_data_at_column_path(value_tag.clone(), &f, v) {
Some(f) => match obj.insert_data_at_column_path(value_tag.clone(), f, v) {
Some(v) => return Ok(v),
None => {
return Err(ShellError::labeled_error(
format!(
"add could not find place to insert field {:?} {}",
obj,
f.iter().map(|i| &i.item).join(".")
f.iter()
.map(|i| {
match &i.item {
Value::Primitive(primitive) => primitive.format(None),
_ => String::from(""),
}
})
.join(".")
),
"column name",
&value_tag,

View File

@ -12,7 +12,7 @@ enum Action {
Substring(usize, usize),
}
pub type ColumnPath = Vec<Tagged<String>>;
pub type ColumnPath = Tagged<Vec<Tagged<Value>>>;
struct Str {
field: Option<ColumnPath>,
@ -132,7 +132,7 @@ impl Str {
let replace_for = value.item.get_data_by_column_path(
value.tag(),
&f,
f,
Box::new(move |(obj_source, column_path_tried)| {
match did_you_mean(&obj_source, &column_path_tried) {
Some(suggestions) => {
@ -169,7 +169,7 @@ impl Str {
match value.item.replace_data_at_column_path(
value.tag(),
&f,
f,
replacement.item.clone(),
) {
Some(v) => return Ok(v),
@ -246,17 +246,22 @@ impl Plugin for Str {
if let Some(possible_field) = args.nth(0) {
match possible_field {
Tagged {
item: Value::Primitive(Primitive::String(s)),
tag,
} => {
self.for_field(vec![s.clone().tagged(tag)]);
}
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()?);
}
},
table @ Tagged {
item: Value::Table(_),
..
} => {
self.field = Some(table.as_column_path()?.item);
self.field = Some(table.as_column_path()?);
}
_ => {
return Err(ShellError::labeled_error(
@ -419,9 +424,13 @@ mod tests {
.is_ok());
assert_eq!(
plugin
.field
.map(|f| f.into_iter().map(|f| f.item).collect()),
plugin.field.map(|f| f
.iter()
.map(|f| match &f.item {
Value::Primitive(Primitive::String(s)) => s.clone(),
_ => panic!(""),
})
.collect()),
Some(vec!["package".to_string(), "description".to_string()])
)
}