Merge pull request #573 from androbtech/embed

can embed a new field to the table.
This commit is contained in:
Andrés N. Robalino 2019-09-02 01:14:06 -05:00 committed by GitHub
commit 2cb290b77b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 153 additions and 2 deletions

View File

@ -105,6 +105,10 @@ path = "src/plugins/inc.rs"
name = "nu_plugin_sum"
path = "src/plugins/sum.rs"
[[bin]]
name = "nu_plugin_embed"
path = "src/plugins/embed.rs"
[[bin]]
name = "nu_plugin_add"
path = "src/plugins/add.rs"

View File

@ -234,6 +234,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| where condition | Filter table to match the condition |
| inc (field) | Increment a value or version. Optional use the field of a table |
| add field value | Add a new field to the table |
| embed field | Embeds a new field to the table |
| sum | Sum a column of values |
| edit field value | Edit an existing field to have a new value |
| reverse | Reverses the table. |
@ -250,7 +251,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
| to-toml | Convert table into .toml text |
| to-yaml | Convert table into .yaml text |
| to-bson | Convert table into .bson text |
| to-csv | Convert table into .csv text |
| to-csv | Convert table into .csv text |
| to-bson | Convert table into .bson binary data |
| to-tsv | Convert table into .tsv text |
| to-sqlite | Convert table to sqlite .db binary data |

View File

@ -100,8 +100,9 @@ impl Dictionary {
}
}
#[derive(Debug)]
pub struct TaggedListBuilder {
tag: Tag,
pub tag: Tag,
list: Vec<Tagged<Value>>,
}

87
src/plugins/embed.rs Normal file
View File

@ -0,0 +1,87 @@
use nu::{
serve_plugin, CallInfo, Plugin, Primitive, ReturnSuccess, ReturnValue, ShellError, Signature,
SyntaxType, Tag, Tagged, TaggedDictBuilder, Value,
};
struct Embed {
field: Option<String>,
values: Vec<Tagged<Value>>,
}
impl Embed {
fn new() -> Embed {
Embed {
field: None,
values: Vec::new(),
}
}
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::string(
"embed needs a field when embedding a value",
)),
},
}
}
}
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", SyntaxType::String)
.rest(SyntaxType::String)
.filter())
}
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
if let Some(args) = call_info.args.positional {
match &args[0] {
Tagged {
item: Value::Primitive(Primitive::String(s)),
..
} => {
self.field = Some(s.clone());
self.values = Vec::new();
}
_ => {
return Err(ShellError::string(format!(
"Unrecognized type in params: {:?}",
args[0]
)))
}
}
}
Ok(vec![])
}
fn filter(&mut self, input: Tagged<Value>) -> Result<Vec<ReturnValue>, ShellError> {
self.embed(input)?;
Ok(vec![])
}
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::List(self.values.clone()),
tag: Tag::unknown(),
},
);
Ok(vec![ReturnSuccess::value(root.into_tagged_value())])
}
}
fn main() {
serve_plugin(&mut Embed::new());
}

View File

@ -508,3 +508,61 @@ fn can_get_reverse_first() {
assert_eq!(actual, "utf16.ini");
}
#[test]
fn embed() {
Playground::setup("embed_test", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| embed caballeros
| get caballeros
| nth 0
| get last_name
| echo $it
"#
));
assert_eq!(actual, "Robalino");
})
}
#[test]
fn get() {
Playground::setup("get_test", |dirs, sandbox| {
sandbox.with_files(vec![FileWithContentToBeTrimmed(
"los_tres_caballeros.txt",
r#"
first_name,last_name
Andrés,Robalino
Jonathan,Turner
Yehuda,Katz
"#,
)]);
let actual = nu!(
cwd: dirs.test(), h::pipeline(
r#"
open los_tres_caballeros.txt
| from-csv
| nth 1
| get last_name
| echo $it
"#
));
assert_eq!(actual, "Turner");
})
}