Add new line primitive, bump version, allow bare filepaths

This commit is contained in:
Jonathan Turner 2019-12-03 19:44:59 +13:00
parent 3fa03eb7a4
commit efc879b955
37 changed files with 170 additions and 129 deletions

2
Cargo.lock generated
View File

@ -1878,7 +1878,7 @@ dependencies = [
[[package]]
name = "nu"
version = "0.6.1"
version = "0.6.2"
dependencies = [
"ansi_term 0.12.1",
"app_dirs",

View File

@ -1,6 +1,6 @@
[package]
name = "nu"
version = "0.6.1"
version = "0.6.2"
authors = ["Yehuda Katz <wycats@gmail.com>", "Jonathan Turner <jonathan.d.turner@gmail.com>", "Andrés N. Robalino <andres@androbtech.com>"]
description = "A shell for the GitHub era"
license = "MIT"

View File

@ -102,10 +102,17 @@ impl ExpandExpression for FilePathShape {
token_nodes: &mut TokensIterator<'_>,
context: &ExpandContext,
) -> Result<hir::Expression, ParseError> {
let atom = expand_atom(token_nodes, "file path", context, ExpansionRule::new())?;
let atom = expand_atom(
token_nodes,
"file path",
context,
ExpansionRule::new().allow_external_word(),
)?;
match atom.unspanned {
UnspannedAtomicToken::Word { text: body } | UnspannedAtomicToken::String { body } => {
UnspannedAtomicToken::Word { text: body }
| UnspannedAtomicToken::ExternalWord { text: body }
| UnspannedAtomicToken::String { body } => {
let path = expand_file_path(body.slice(context.source), context);
return Ok(hir::Expression::file_path(path, atom.span));
}

View File

@ -84,11 +84,17 @@ impl ExpandExpression for PatternShape {
token_nodes: &mut TokensIterator<'_>,
context: &ExpandContext,
) -> Result<hir::Expression, ParseError> {
let atom = expand_atom(token_nodes, "pattern", context, ExpansionRule::new())?;
let atom = expand_atom(
token_nodes,
"pattern",
context,
ExpansionRule::new().allow_external_word(),
)?;
match atom.unspanned {
UnspannedAtomicToken::Word { text: body }
| UnspannedAtomicToken::String { body }
| UnspannedAtomicToken::ExternalWord { text: body }
| UnspannedAtomicToken::GlobPattern { pattern: body } => {
let path = expand_file_path(body.slice(context.source), context);
return Ok(hir::Expression::pattern(path.to_string_lossy(), atom.span));

View File

@ -132,9 +132,10 @@ impl Value {
self.tag.clone()
}
pub fn as_string(&self) -> Result<&str, ShellError> {
pub fn as_string(&self) -> Result<String, ShellError> {
match &self.value {
UntaggedValue::Primitive(Primitive::String(string)) => Ok(&string[..]),
UntaggedValue::Primitive(Primitive::String(string)) => Ok(string.clone()),
UntaggedValue::Primitive(Primitive::Line(line)) => Ok(line.clone() + "\n"),
_ => Err(ShellError::type_error("string", self.spanned_type_name())),
}
}

View File

@ -31,6 +31,7 @@ impl PrettyType for Primitive {
Primitive::Decimal(_) => ty("decimal"),
Primitive::Bytes(_) => ty("bytesize"),
Primitive::String(_) => ty("string"),
Primitive::Line(_) => ty("line"),
Primitive::ColumnPath(_) => ty("column-path"),
Primitive::Pattern(_) => ty("pattern"),
Primitive::Boolean(_) => ty("boolean"),
@ -52,6 +53,7 @@ impl PrettyDebug for Primitive {
Primitive::Decimal(decimal) => prim(format_args!("{}", decimal)),
Primitive::Bytes(bytes) => primitive_doc(bytes, "bytesize"),
Primitive::String(string) => prim(string),
Primitive::Line(string) => prim(string),
Primitive::ColumnPath(path) => path.pretty(),
Primitive::Pattern(pattern) => primitive_doc(pattern, "pattern"),
Primitive::Boolean(boolean) => match boolean {

View File

@ -17,6 +17,7 @@ pub enum Primitive {
Decimal(BigDecimal),
Bytes(u64),
String(String),
Line(String),
ColumnPath(ColumnPath),
Pattern(String),
Boolean(bool),
@ -51,6 +52,7 @@ impl ShellTypeName for Primitive {
Primitive::Decimal(_) => "decimal",
Primitive::Bytes(_) => "bytes",
Primitive::String(_) => "string",
Primitive::Line(_) => "line",
Primitive::ColumnPath(_) => "column path",
Primitive::Pattern(_) => "pattern",
Primitive::Boolean(_) => "boolean",

View File

@ -152,6 +152,25 @@ pub fn autoview(
} => {
outln!("{}", s);
}
Value {
value: UntaggedValue::Primitive(Primitive::Line(ref s)),
tag: Tag { anchor, span },
} if anchor.is_some() => {
if let Some(text) = text {
let mut stream = VecDeque::new();
stream.push_back(value::string(s).into_value(Tag { anchor, span }));
let result = text.run(raw.with_input(stream.into()), &context.commands);
result.collect::<Vec<_>>().await;
} else {
outln!("{}\n", s);
}
}
Value {
value: UntaggedValue::Primitive(Primitive::Line(s)),
..
} => {
outln!("{}\n", s);
}
Value {
value: UntaggedValue::Primitive(Primitive::Path(s)),
..

View File

@ -25,7 +25,7 @@ impl Encoder for LinesCodec {
}
impl Decoder for LinesCodec {
type Item = String;
type Item = nu_protocol::UntaggedValue;
type Error = Error;
fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
@ -33,12 +33,14 @@ impl Decoder for LinesCodec {
Some(pos) if !src.is_empty() => {
let buf = src.split_to(pos + 1);
String::from_utf8(buf.to_vec())
.map(value::line)
.map(Some)
.map_err(|e| Error::new(ErrorKind::InvalidData, e))
}
_ if !src.is_empty() => {
let drained = src.take();
String::from_utf8(drained.to_vec())
.map(value::string)
.map(Some)
.map_err(|e| Error::new(ErrorKind::InvalidData, e))
}
@ -192,8 +194,7 @@ pub(crate) async fn run_external_command(
let stdout = popen.stdout.take().unwrap();
let file = futures::io::AllowStdIo::new(stdout);
let stream = Framed::new(file, LinesCodec {});
let stream =
stream.map(move |line| value::string(line.unwrap()).into_value(&name_tag));
let stream = stream.map(move |line| line.unwrap().into_value(&name_tag));
Ok(ClassifiedInputStream::from_input_stream(
stream.boxed() as BoxStream<'static, Value>
))

View File

@ -56,19 +56,16 @@ pub fn from_delimited_data(
for value in values {
let value_tag = &value.tag;
latest_tag = Some(value_tag.clone());
match &value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
concat_string.push_str("\n");
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
} else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_tag.clone(),
"value originates from here",
value_tag.clone(),
)),
))
}
}

View File

@ -79,19 +79,16 @@ fn from_ini(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStrea
for value in values {
latest_tag = Some(value.tag.clone());
let value_span = value.tag.span;
match &value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
concat_string.push_str("\n");
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
} else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
span,
"value originates from here",
value_span,
)),
))
}
}

View File

@ -83,19 +83,17 @@ fn from_json(
for value in values {
latest_tag = Some(value.tag.clone());
let value_span = value.tag.span;
match &value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
concat_string.push_str("\n");
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
} else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
)),
))
}
}

View File

@ -266,17 +266,17 @@ fn from_ssv(
for value in values {
let value_tag = value.tag.clone();
latest_tag = Some(value_tag.clone());
match &value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
}
_ => yield Err(ShellError::labeled_error_with_secondary (
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
}
else {
yield Err(ShellError::labeled_error_with_secondary (
"Expected a string from pipeline",
"requires string input",
&name,
"value originates from here",
&value_tag
)),
))
}
}

View File

@ -82,19 +82,17 @@ pub fn from_toml(
for value in values {
latest_tag = Some(value.tag.clone());
let value_span = value.tag.span;
match value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
concat_string.push_str("\n");
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
}
else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
)),
))
}
}

View File

@ -3,7 +3,7 @@ use crate::data::value;
use crate::data::TaggedDictBuilder;
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
use nu_protocol::{ReturnSuccess, Signature, Value};
pub struct FromURL;
@ -44,18 +44,16 @@ fn from_url(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStrea
for value in values {
latest_tag = Some(value.tag.clone());
let value_span = value.tag.span;
match value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
} else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
)),
))
}
}

View File

@ -96,19 +96,17 @@ fn from_xml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStrea
latest_tag = Some(value.tag.clone());
let value_span = value.tag.span;
match value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
concat_string.push_str("\n");
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
}
else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
)),
))
}
}

View File

@ -110,19 +110,17 @@ fn from_yaml(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStre
latest_tag = Some(value.tag.clone());
let value_span = value.tag.span;
match &value.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
concat_string.push_str(&s);
concat_string.push_str("\n");
}
_ => yield Err(ShellError::labeled_error_with_secondary(
if let Ok(s) = value.as_string() {
concat_string.push_str(&s);
}
else {
yield Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
value_span,
)),
))
}
}

View File

@ -38,8 +38,8 @@ fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
let stream = input
.values
.map(move |v| match v.value {
UntaggedValue::Primitive(Primitive::String(s)) => {
.map(move |v| {
if let Ok(s) = v.as_string() {
let split_result: Vec<_> = s.lines().filter(|s| s.trim() != "").collect();
trace!("split result = {:?}", split_result);
@ -47,12 +47,11 @@ fn lines(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream,
let mut result = VecDeque::new();
for s in split_result {
result.push_back(ReturnSuccess::value(
UntaggedValue::Primitive(Primitive::String(s.into())).into_untagged_value(),
UntaggedValue::Primitive(Primitive::Line(s.into())).into_untagged_value(),
));
}
result
}
_ => {
} else {
let mut result = VecDeque::new();
let value_span = v.tag.span;

View File

@ -146,7 +146,7 @@ fn save(
}
_ => {
yield Err(ShellError::labeled_error(
"Save requires a filepath (1)",
"Save requires a filepath",
"needs path",
name_tag.clone(),
));
@ -154,7 +154,7 @@ fn save(
},
None => {
yield Err(ShellError::labeled_error(
"Save requires a filepath (2)",
"Save requires a filepath",
"needs path",
name_tag.clone(),
));
@ -162,7 +162,7 @@ fn save(
}
} else {
yield Err(ShellError::labeled_error(
"Save requires a filepath (3)",
"Save requires a filepath",
"needs path",
name_tag.clone(),
));

View File

@ -2,7 +2,7 @@ use crate::commands::WholeStreamCommand;
use crate::data::{value, TaggedDictBuilder};
use crate::prelude::*;
use nu_errors::ShellError;
use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
use nu_protocol::{ReturnSuccess, Signature, Value};
pub struct Size;
@ -35,17 +35,18 @@ fn size(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream,
Ok(input
.values
.map(move |v| match v.value {
UntaggedValue::Primitive(Primitive::String(ref s)) => {
ReturnSuccess::value(count(s, &v.tag))
.map(move |v| {
if let Ok(s) = v.as_string() {
ReturnSuccess::value(count(&s, &v.tag))
} else {
Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
v.tag.span,
))
}
_ => Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
v.tag.span,
)),
})
.to_output_stream())
}

View File

@ -57,8 +57,8 @@ fn split_column(
Ok(input
.values
.map(move |v| match v.value {
UntaggedValue::Primitive(Primitive::String(ref s)) => {
.map(move |v| {
if let Ok(s) = v.as_string() {
let splitter = separator.replace("\\n", "\n");
trace!("splitting with {:?}", splitter);
@ -104,14 +104,15 @@ fn split_column(
}
ReturnSuccess::value(dict.into_value())
}
} else {
Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
v.tag.span,
))
}
_ => Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",
"requires string input",
name_span,
"value originates from here",
v.tag.span,
)),
})
.to_output_stream())
}

View File

@ -44,8 +44,8 @@ fn split_row(
) -> Result<OutputStream, ShellError> {
let stream = input
.values
.map(move |v| match v.value {
UntaggedValue::Primitive(Primitive::String(ref s)) => {
.map(move |v| {
if let Ok(s) = v.as_string() {
let splitter = separator.item.replace("\\n", "\n");
trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
@ -59,8 +59,7 @@ fn split_row(
));
}
result
}
_ => {
} else {
let mut result = VecDeque::new();
result.push_back(Err(ShellError::labeled_error_with_secondary(
"Expected a string from pipeline",

View File

@ -56,6 +56,7 @@ pub fn value_to_bson_value(v: &Value) -> Result<Bson, ShellError> {
}
UntaggedValue::Primitive(Primitive::Nothing) => Bson::Null,
UntaggedValue::Primitive(Primitive::String(s)) => Bson::String(s.clone()),
UntaggedValue::Primitive(Primitive::Line(s)) => Bson::String(s.clone()),
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => Bson::Array(
path.iter()
.map(|x| match &x.unspanned {

View File

@ -137,6 +137,7 @@ fn to_string_tagged_value(v: &Value) -> Result<String, ShellError> {
UntaggedValue::Primitive(Primitive::Path(_)) => Ok(v.as_string()?.to_string()),
UntaggedValue::Table(_) => return Ok(String::from("[Table]")),
UntaggedValue::Row(_) => return Ok(String::from("[Row]")),
UntaggedValue::Primitive(Primitive::Line(s)) => return Ok(s.to_string()),
UntaggedValue::Primitive(Primitive::String(s)) => return Ok(s.to_string()),
_ => {
return Err(ShellError::labeled_error(

View File

@ -54,6 +54,7 @@ pub fn value_to_json_value(v: &Value) -> Result<serde_json::Value, ShellError> {
UntaggedValue::Primitive(Primitive::Nothing) => serde_json::Value::Null,
UntaggedValue::Primitive(Primitive::Pattern(s)) => serde_json::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::String(s)) => serde_json::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::Line(s)) => serde_json::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => serde_json::Value::Array(
path.iter()
.map(|x| match &x.unspanned {

View File

@ -94,6 +94,7 @@ fn nu_value_to_sqlite_string(v: Value) -> String {
Primitive::Bytes(u) => format!("{}", u),
Primitive::Pattern(s) => format!("'{}'", s.replace("'", "''")),
Primitive::String(s) => format!("'{}'", s.replace("'", "''")),
Primitive::Line(s) => format!("'{}'", s.replace("'", "''")),
Primitive::Boolean(true) => "1".into(),
Primitive::Boolean(_) => "0".into(),
Primitive::Date(d) => format!("'{}'", d),

View File

@ -50,6 +50,7 @@ pub fn value_to_toml_value(v: &Value) -> Result<toml::Value, ShellError> {
}
UntaggedValue::Primitive(Primitive::Pattern(s)) => toml::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::String(s)) => toml::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::Line(s)) => toml::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::Path(s)) => {
toml::Value::String(s.display().to_string())
}

View File

@ -51,6 +51,7 @@ pub fn value_to_yaml_value(v: &Value) -> Result<serde_yaml::Value, ShellError> {
UntaggedValue::Primitive(Primitive::Nothing) => serde_yaml::Value::Null,
UntaggedValue::Primitive(Primitive::Pattern(s)) => serde_yaml::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::String(s)) => serde_yaml::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::Line(s)) => serde_yaml::Value::String(s.clone()),
UntaggedValue::Primitive(Primitive::ColumnPath(path)) => {
let mut out = vec![];

View File

@ -186,6 +186,9 @@ fn coerce_compare_primitive(
CompareValues::Decimals(BigDecimal::from(*left), right.clone())
}
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
(Line(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
(String(left), Line(right)) => CompareValues::String(left.clone(), right.clone()),
(Line(left), Line(right)) => CompareValues::String(left.clone(), right.clone()),
(Date(left), Date(right)) => CompareValues::Date(left.clone(), right.clone()),
(Date(left), Duration(right)) => CompareValues::DateDuration(left.clone(), right.clone()),
_ => return Err((left.type_name(), right.type_name())),

View File

@ -33,6 +33,7 @@ pub enum TypeShape {
Decimal,
Bytesize,
String,
Line,
ColumnPath,
Pattern,
Boolean,
@ -62,6 +63,7 @@ impl TypeShape {
Primitive::Decimal(_) => TypeShape::Decimal,
Primitive::Bytes(_) => TypeShape::Bytesize,
Primitive::String(_) => TypeShape::String,
Primitive::Line(_) => TypeShape::Line,
Primitive::ColumnPath(_) => TypeShape::ColumnPath,
Primitive::Pattern(_) => TypeShape::Pattern,
Primitive::Boolean(_) => TypeShape::Boolean,
@ -114,6 +116,7 @@ impl PrettyDebug for TypeShape {
TypeShape::Decimal => ty("decimal"),
TypeShape::Bytesize => ty("bytesize"),
TypeShape::String => ty("string"),
TypeShape::Line => ty("line"),
TypeShape::ColumnPath => ty("column-path"),
TypeShape::Pattern => ty("pattern"),
TypeShape::Boolean => ty("boolean"),
@ -208,6 +211,7 @@ pub enum InlineShape {
Decimal(BigDecimal),
Bytesize(u64),
String(String),
Line(String),
ColumnPath(ColumnPath),
Pattern(String),
Boolean(bool),
@ -242,6 +246,7 @@ impl InlineShape {
Primitive::Decimal(decimal) => InlineShape::Decimal(decimal.clone()),
Primitive::Bytes(bytesize) => InlineShape::Bytesize(*bytesize),
Primitive::String(string) => InlineShape::String(string.clone()),
Primitive::Line(string) => InlineShape::Line(string.clone()),
Primitive::ColumnPath(path) => InlineShape::ColumnPath(path.clone()),
Primitive::Pattern(pattern) => InlineShape::Pattern(pattern.clone()),
Primitive::Boolean(boolean) => InlineShape::Boolean(*boolean),
@ -327,6 +332,7 @@ impl PrettyDebug for FormatInlineShape {
}
}
InlineShape::String(string) => b::primitive(format!("{}", string)),
InlineShape::Line(string) => b::primitive(format!("{}", string)),
InlineShape::ColumnPath(path) => {
b::intersperse(path.iter().map(|member| member.pretty()), b::keyword("."))
}

View File

@ -37,6 +37,7 @@ pub fn format_primitive(primitive: &Primitive, field_name: Option<&String>) -> S
Primitive::Decimal(decimal) => format!("{}", decimal),
Primitive::Pattern(s) => format!("{}", s),
Primitive::String(s) => format!("{}", s),
Primitive::Line(s) => format!("{}", s),
Primitive::ColumnPath(p) => {
let mut members = p.iter();
let mut f = String::new();

View File

@ -86,6 +86,10 @@ impl ExtractType for String {
value: UntaggedValue::Primitive(Primitive::String(string)),
..
} => Ok(string.clone()),
Value {
value: UntaggedValue::Primitive(Primitive::Line(string)),
..
} => Ok(string.clone()),
other => Err(ShellError::type_error("String", other.spanned_type_name())),
}
}

View File

@ -27,6 +27,10 @@ pub fn string(s: impl Into<String>) -> UntaggedValue {
UntaggedValue::Primitive(Primitive::String(s.into()))
}
pub fn line(s: impl Into<String>) -> UntaggedValue {
UntaggedValue::Primitive(Primitive::Line(s.into()))
}
pub fn column_path(s: Vec<impl Into<PathMember>>) -> UntaggedValue {
UntaggedValue::Primitive(Primitive::ColumnPath(ColumnPath::new(
s.into_iter().map(|p| p.into()).collect(),

View File

@ -72,16 +72,14 @@ impl Plugin for Match {
tag,
} => {
if let Some(val) = dict.entries.get(&self.column) {
match val {
Value {
value: UntaggedValue::Primitive(Primitive::String(s)),
..
} => {
flag = self.regex.is_match(s);
}
Value { tag, .. } => {
return Err(ShellError::labeled_error("expected string", "value", tag));
}
if let Ok(s) = val.as_string() {
flag = self.regex.is_match(&s);
} else {
return Err(ShellError::labeled_error(
"expected string",
"value",
val.tag(),
));
}
} else {
return Err(ShellError::labeled_error(

View File

@ -129,24 +129,16 @@ impl Plugin for Parse {
fn filter(&mut self, input: Value) -> Result<Vec<ReturnValue>, ShellError> {
let mut results = vec![];
match &input {
Value {
tag,
value: UntaggedValue::Primitive(Primitive::String(s)),
} => {
//self.full_input.push_str(&s);
if let Ok(s) = input.as_string() {
for cap in self.regex.captures_iter(&s) {
let mut dict = TaggedDictBuilder::new(input.tag());
for cap in self.regex.captures_iter(&s) {
let mut dict = TaggedDictBuilder::new(tag);
for (idx, column_name) in self.column_names.iter().enumerate() {
dict.insert_untagged(column_name, value::string(&cap[idx + 1].to_string()));
}
results.push(ReturnSuccess::value(dict.into_value()));
for (idx, column_name) in self.column_names.iter().enumerate() {
dict.insert_untagged(column_name, value::string(&cap[idx + 1].to_string()));
}
results.push(ReturnSuccess::value(dict.into_value()));
}
_ => {}
}
Ok(results)
}

View File

@ -155,6 +155,9 @@ impl Str {
UntaggedValue::Primitive(Primitive::String(ref s)) => {
Ok(self.apply(&s)?.into_value(value.tag()))
}
UntaggedValue::Primitive(Primitive::Line(ref s)) => {
Ok(self.apply(&s)?.into_value(value.tag()))
}
UntaggedValue::Row(_) => match self.field {
Some(ref f) => {
let fields = f.clone();

View File

@ -30,6 +30,7 @@ fn converts_structured_table_to_csv_text() {
r#"
open csv_text_sample.txt
| lines
| trim
| split-column "," a b c d origin
| last 1
| to-csv
@ -60,6 +61,7 @@ fn converts_structured_table_to_csv_text_skipping_headers_after_conversion() {
r#"
open csv_text_sample.txt
| lines
| trim
| split-column "," a b c d origin
| last 1
| to-csv --headerless