Merge pull request #848 from andrasio/column_path-inc

Inc plugin increments appropiately given a table containing a version.
This commit is contained in:
Jonathan Turner
2019-10-20 07:27:47 +13:00
committed by GitHub
4 changed files with 164 additions and 33 deletions

View File

@ -1,6 +1,9 @@
#[macro_use]
extern crate indexmap;
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SyntaxShape, Tag, Tagged, TaggedDictBuilder, Value,
SyntaxShape, Tag, Tagged, TaggedItem, Value,
};
struct Embed {
@ -16,22 +19,8 @@ impl Embed {
}
fn embed(&mut self, value: Tagged<Value>) -> Result<(), ShellError> {
match value {
Tagged { item, tag } => match &self.field {
Some(_) => {
self.values.push(Tagged {
item: item,
tag: tag,
});
Ok(())
}
None => Err(ShellError::labeled_error(
"embed needs a field when embedding a value",
"original value",
&tag,
)),
},
}
self.values.push(value);
Ok(())
}
}
@ -39,8 +28,7 @@ impl Plugin for Embed {
fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("embed")
.desc("Embeds a new field to the table.")
.required("Field", SyntaxShape::String)
.rest(SyntaxShape::String)
.optional("field", SyntaxShape::String)
.filter())
}
@ -67,15 +55,15 @@ impl Plugin for Embed {
}
fn end_filter(&mut self) -> Result<Vec<ReturnValue>, ShellError> {
let mut root = TaggedDictBuilder::new(Tag::unknown());
root.insert_tagged(
self.field.as_ref().unwrap(),
Tagged {
item: Value::Table(self.values.clone()),
tag: Tag::unknown(),
},
);
Ok(vec![ReturnSuccess::value(root.into_tagged_value())])
let row = Value::row(indexmap! {
match &self.field {
Some(key) => key.clone(),
None => "root".into(),
} => Value::table(&self.values).tagged(Tag::unknown()),
})
.tagged(Tag::unknown());
Ok(vec![ReturnSuccess::value(row)])
}
}

View File

@ -14,7 +14,7 @@ pub enum SemVerAction {
Patch,
}
pub type ColumnPath = Tagged<Vec<Tagged<String>>>;
pub type ColumnPath = Vec<Tagged<String>>;
struct Inc {
field: Option<ColumnPath>,
@ -83,6 +83,16 @@ impl Inc {
Ok(Value::bytes(b + 1 as u64).tagged(value.tag()))
}
Value::Primitive(Primitive::String(ref s)) => Ok(self.apply(&s)?.tagged(value.tag())),
Value::Table(values) => {
if values.len() == 1 {
return Ok(Value::Table(vec![self.inc(values[0].clone())?]).tagged(value.tag()));
} else {
return Err(ShellError::type_error(
"incrementable value",
value.tagged_type_name(),
));
}
}
Value::Row(_) => match self.field {
Some(ref f) => {
let replacement = match value.item.get_data_by_column_path(value.tag(), f) {
@ -91,10 +101,11 @@ impl Inc {
return Err(ShellError::labeled_error(
"inc could not find field to replace",
"column name",
&f.tag,
value.tag(),
))
}
};
match value.item.replace_data_at_column_path(
value.tag(),
f,
@ -105,7 +116,7 @@ impl Inc {
return Err(ShellError::labeled_error(
"inc could not find field to replace",
"column name",
&f.tag,
value.tag(),
))
}
}
@ -151,7 +162,7 @@ impl Plugin for Inc {
item: Value::Table(_),
..
} => {
self.field = Some(table.as_column_path()?);
self.field = Some(table.as_column_path()?.item().to_vec());
}
value => return Err(ShellError::type_error("table", value.tagged_type_name())),
}