initial change to Tagged<Value>

This commit is contained in:
Jonathan Turner
2019-08-01 13:58:42 +12:00
parent c61a1108ff
commit 462f783fac
78 changed files with 713 additions and 1040 deletions

View File

@@ -5,7 +5,7 @@ use crate::prelude::*;
pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
if args.input.len() > 0 {
if let Spanned {
if let Tagged {
item: Value::Binary(_),
..
} = args.input[0]
@@ -28,7 +28,7 @@ pub fn autoview(args: SinkCommandArgs) -> Result<(), ShellError> {
Ok(())
}
fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool {
fn equal_shapes(input: &Vec<Tagged<Value>>) -> bool {
let mut items = input.iter();
let item = match items.next() {
@@ -47,11 +47,11 @@ fn equal_shapes(input: &Vec<Spanned<Value>>) -> bool {
true
}
fn is_single_text_value(input: &Vec<Spanned<Value>>) -> bool {
fn is_single_text_value(input: &Vec<Tagged<Value>>) -> bool {
if input.len() != 1 {
return false;
}
if let Spanned {
if let Tagged {
item: Value::Primitive(Primitive::String(_)),
..
} = input[0]

View File

@@ -25,7 +25,7 @@ pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error(
"Can not change to directory",
"directory not found",
v.span.clone(),
v.span().clone(),
));
}
}
@@ -40,7 +40,7 @@ pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error(
"Can not change to directory",
"directory not found",
args.nth(0).unwrap().span.clone(),
args.nth(0).unwrap().span().clone(),
));
} else {
return Err(ShellError::string("Can not change to directory"));

View File

@@ -1,6 +1,6 @@
use crate::commands::command::Sink;
use crate::context::SourceMap;
use crate::parser::{registry::Args, Span, Spanned, TokenNode};
use crate::parser::{registry::Args, TokenNode};
use crate::prelude::*;
use bytes::{BufMut, BytesMut};
use futures::stream::StreamExt;
@@ -105,11 +105,7 @@ crate struct SinkCommand {
}
impl SinkCommand {
crate fn run(
self,
context: &mut Context,
input: Vec<Spanned<Value>>,
) -> Result<(), ShellError> {
crate fn run(self, context: &mut Context, input: Vec<Tagged<Value>>) -> Result<(), ShellError> {
context.run_sink(self.command, self.name_span.clone(), self.args, input)
}
}
@@ -173,7 +169,7 @@ crate struct ExternalCommand {
crate name: String,
#[allow(unused)]
crate name_span: Option<Span>,
crate args: Vec<Spanned<String>>,
crate args: Vec<Tagged<String>>,
}
crate enum StreamNext {
@@ -190,7 +186,7 @@ impl ExternalCommand {
stream_next: StreamNext,
) -> Result<ClassifiedInputStream, ShellError> {
let stdin = input.stdin;
let inputs: Vec<Spanned<Value>> = input.objects.into_vec().await;
let inputs: Vec<Tagged<Value>> = input.objects.into_vec().await;
let name_span = self.name_span.clone();
trace!(target: "nu::run::external", "-> {}", self.name);
@@ -215,7 +211,7 @@ impl ExternalCommand {
let mut span = None;
for arg in &self.args {
if arg.item.contains("$it") {
span = Some(arg.span);
span = Some(arg.span());
}
}
if let Some(span) = span {
@@ -260,7 +256,7 @@ impl ExternalCommand {
let mut span = None;
for arg in &self.args {
if arg.item.contains("$it") {
span = Some(arg.span);
span = Some(arg.span());
}
}
return Err(ShellError::maybe_labeled_error(
@@ -322,10 +318,9 @@ impl ExternalCommand {
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()).spanned(name_span));
let stream = stream.map(move |line| Value::string(line.unwrap()).tagged(name_span));
Ok(ClassifiedInputStream::from_input_stream(
stream.boxed() as BoxStream<'static, Spanned<Value>>
stream.boxed() as BoxStream<'static, Tagged<Value>>
))
}
}

View File

@@ -2,10 +2,7 @@ use crate::context::SourceMap;
use crate::context::SpanSource;
use crate::errors::ShellError;
use crate::object::Value;
use crate::parser::{
registry::{self, Args},
Span, Spanned,
};
use crate::parser::registry::{self, Args};
use crate::prelude::*;
use getset::Getters;
use serde::{Deserialize, Serialize};
@@ -29,15 +26,15 @@ pub struct CommandArgs {
}
impl CommandArgs {
pub fn nth(&self, pos: usize) -> Option<&Spanned<Value>> {
pub fn nth(&self, pos: usize) -> Option<&Tagged<Value>> {
self.call_info.args.nth(pos)
}
pub fn positional_iter(&self) -> impl Iterator<Item = &Spanned<Value>> {
pub fn positional_iter(&self) -> impl Iterator<Item = &Tagged<Value>> {
self.call_info.args.positional_iter()
}
pub fn expect_nth(&self, pos: usize) -> Result<&Spanned<Value>, ShellError> {
pub fn expect_nth(&self, pos: usize) -> Result<&Tagged<Value>, ShellError> {
self.call_info.args.expect_nth(pos)
}
@@ -45,7 +42,7 @@ impl CommandArgs {
self.call_info.args.len()
}
pub fn get(&self, name: &str) -> Option<&Spanned<Value>> {
pub fn get(&self, name: &str) -> Option<&Tagged<Value>> {
self.call_info.args.get(name)
}
@@ -58,7 +55,7 @@ impl CommandArgs {
pub struct SinkCommandArgs {
pub ctx: Context,
pub call_info: CallInfo,
pub input: Vec<Spanned<Value>>,
pub input: Vec<Tagged<Value>>,
}
#[derive(Debug, Serialize, Deserialize)]
@@ -70,14 +67,14 @@ pub enum CommandAction {
#[derive(Debug, Serialize, Deserialize)]
pub enum ReturnSuccess {
Value(Spanned<Value>),
Value(Tagged<Value>),
Action(CommandAction),
}
pub type ReturnValue = Result<ReturnSuccess, ShellError>;
impl From<Spanned<Value>> for ReturnValue {
fn from(input: Spanned<Value>) -> ReturnValue {
impl From<Tagged<Value>> for ReturnValue {
fn from(input: Tagged<Value>) -> ReturnValue {
Ok(ReturnSuccess::Value(input))
}
}
@@ -87,7 +84,7 @@ impl ReturnSuccess {
Ok(ReturnSuccess::Action(CommandAction::ChangePath(path)))
}
pub fn value(input: impl Into<Spanned<Value>>) -> ReturnValue {
pub fn value(input: impl Into<Tagged<Value>>) -> ReturnValue {
Ok(ReturnSuccess::Value(input.into()))
}
@@ -96,7 +93,7 @@ impl ReturnSuccess {
}
pub fn spanned_value(input: Value, span: Span) -> ReturnValue {
Ok(ReturnSuccess::Value(Spanned::from_item(input, span)))
Ok(ReturnSuccess::Value(Tagged::from_item(input, span)))
}
}

View File

@@ -62,7 +62,7 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write_config(&result)?;
return Ok(
stream![Spanned::from_item(Value::Object(result.into()), v.span())]
stream![Tagged::from_item(Value::Object(result.into()), v.span())]
.from_input_stream(),
);
}
@@ -74,7 +74,7 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
config::write_config(&result)?;
return Ok(
stream![Spanned::from_item(Value::Object(result.into()), c.span())].from_input_stream(),
stream![Tagged::from_item(Value::Object(result.into()), c.span())].from_input_stream(),
);
}
@@ -90,12 +90,12 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
)));
}
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).spanned(v)]);
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).tagged(v)]);
return Ok(obj.from_input_stream());
}
if args.len() == 0 {
return Ok(vec![Value::Object(result.into()).spanned(args.call_info.name_span)].into());
return Ok(vec![Value::Object(result.into()).tagged(args.call_info.name_span)].into());
}
Err(ShellError::string(format!("Unimplemented")))

View File

@@ -1,6 +1,5 @@
use crate::errors::ShellError;
use crate::object::{Dictionary, Value};
use crate::parser::Spanned;
use crate::prelude::*;
use chrono::{DateTime, Local, Utc};
@@ -35,7 +34,7 @@ impl Command for Date {
}
}
pub fn date_to_value<T: TimeZone>(dt: DateTime<T>, span: Span) -> Spanned<Value>
pub fn date_to_value<T: TimeZone>(dt: DateTime<T>, span: Span) -> Tagged<Value>
where
T::Offset: Display,
{
@@ -43,60 +42,36 @@ where
indexmap.insert(
"year".to_string(),
Spanned {
item: Value::int(dt.year()),
span,
},
Tagged::from_item(Value::int(dt.year()), span),
);
indexmap.insert(
"month".to_string(),
Spanned {
item: Value::int(dt.month()),
span,
},
Tagged::from_item(Value::int(dt.month()), span),
);
indexmap.insert(
"day".to_string(),
Spanned {
item: Value::int(dt.day()),
span,
},
Tagged::from_item(Value::int(dt.day()), span),
);
indexmap.insert(
"hour".to_string(),
Spanned {
item: Value::int(dt.hour()),
span,
},
Tagged::from_item(Value::int(dt.hour()), span),
);
indexmap.insert(
"minute".to_string(),
Spanned {
item: Value::int(dt.minute()),
span,
},
Tagged::from_item(Value::int(dt.minute()), span),
);
indexmap.insert(
"second".to_string(),
Spanned {
item: Value::int(dt.second()),
span,
},
Tagged::from_item(Value::int(dt.second()), span),
);
let tz = dt.offset();
indexmap.insert(
"timezone".to_string(),
Spanned {
item: Value::string(format!("{}", tz)),
span,
},
Tagged::from_item(Value::string(format!("{}", tz)), span),
);
Spanned {
item: Value::Object(Dictionary::from(indexmap)),
span,
}
Tagged::from_item(Value::Object(Dictionary::from(indexmap)), span)
}
pub fn date(args: CommandArgs) -> Result<OutputStream, ShellError> {

View File

@@ -20,7 +20,7 @@ pub fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error(
"Value is not a number",
"expected integer",
args.expect_nth(0)?.span,
args.expect_nth(0)?.span(),
))
}
};

View File

@@ -1,12 +1,11 @@
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
use csv::ReaderBuilder;
pub fn from_csv_string_to_value(
s: String,
span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> {
) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let mut reader = ReaderBuilder::new()
.has_headers(false)
.from_reader(s.as_bytes());
@@ -28,25 +27,22 @@ pub fn from_csv_string_to_value(
if let Some(row_values) = iter.next() {
let row_values = row_values?;
let mut row = SpannedDictBuilder::new(span);
let mut row = TaggedDictBuilder::new(span);
for (idx, entry) in row_values.iter().enumerate() {
row.insert_spanned(
row.insert_tagged(
fields.get(idx).unwrap(),
Value::Primitive(Primitive::String(String::from(entry))).spanned(span),
Value::Primitive(Primitive::String(String::from(entry))).tagged(span),
);
}
rows.push(row.into_spanned_value());
rows.push(row.into_tagged_value());
} else {
break;
}
}
Ok(Spanned {
item: Value::List(rows),
span,
})
Ok(Tagged::from_item(Value::List(rows), span))
}
pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
@@ -55,20 +51,25 @@ pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(out
.values
.map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_csv_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as CSV",
"piped data failed CSV parse",
.map(move |a| {
let value_span = a.span();
match a.item {
Value::Primitive(Primitive::String(s)) => {
match from_csv_string_to_value(s, value_span) {
Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as CSV",
"piped data failed CSV parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
},
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}
})
.to_output_stream())
}

View File

@@ -1,38 +1,38 @@
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
use std::collections::HashMap;
fn convert_ini_second_to_nu_value(
v: &HashMap<String, String>,
span: impl Into<Span>,
) -> Spanned<Value> {
let mut second = SpannedDictBuilder::new(span);
) -> Tagged<Value> {
let mut second = TaggedDictBuilder::new(span);
for (key, value) in v.into_iter() {
second.insert(key.clone(), Primitive::String(value.clone()));
}
second.into_spanned_value()
second.into_tagged_value()
}
fn convert_ini_top_to_nu_value(
v: &HashMap<String, HashMap<String, String>>,
span: impl Into<Span>,
) -> Spanned<Value> {
) -> Tagged<Value> {
let span = span.into();
let mut top_level = SpannedDictBuilder::new(span);
let mut top_level = TaggedDictBuilder::new(span);
for (key, value) in v.iter() {
top_level.insert_spanned(key.clone(), convert_ini_second_to_nu_value(value, span));
top_level.insert_tagged(key.clone(), convert_ini_second_to_nu_value(value, span));
}
top_level.into_spanned_value()
top_level.into_tagged_value()
}
pub fn from_ini_string_to_value(
s: String,
span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> {
) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let v: HashMap<String, HashMap<String, String>> = serde_ini::from_str(&s)?;
Ok(convert_ini_top_to_nu_value(&v, span))
}
@@ -42,20 +42,25 @@ pub fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span;
Ok(out
.values
.map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_ini_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as INI",
"piped data failed INI parse",
.map(move |a| {
let value_span = a.span();
match a.item {
Value::Primitive(Primitive::String(s)) => {
match from_ini_string_to_value(s, value_span) {
Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as INI",
"piped data failed INI parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
},
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}
})
.to_output_stream())
}

View File

@@ -1,36 +1,36 @@
use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>) -> Spanned<Value> {
fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into();
match v {
serde_hjson::Value::Null => {
Value::Primitive(Primitive::String(String::from(""))).spanned(span)
Value::Primitive(Primitive::String(String::from(""))).tagged(span)
}
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).spanned(span),
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
serde_hjson::Value::F64(n) => {
Value::Primitive(Primitive::Float(OF64::from(*n))).spanned(span)
Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span)
}
serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).spanned(span),
serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).spanned(span),
serde_hjson::Value::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(span),
serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(span),
serde_hjson::Value::String(s) => {
Value::Primitive(Primitive::String(String::from(s))).spanned(span)
Value::Primitive(Primitive::String(String::from(s))).tagged(span)
}
serde_hjson::Value::Array(a) => Value::List(
a.iter()
.map(|x| convert_json_value_to_nu_value(x, span))
.collect(),
)
.spanned(span),
.tagged(span),
serde_hjson::Value::Object(o) => {
let mut collected = SpannedDictBuilder::new(span);
let mut collected = TaggedDictBuilder::new(span);
for (k, v) in o.iter() {
collected.insert_spanned(k.clone(), convert_json_value_to_nu_value(v, span));
collected.insert_tagged(k.clone(), convert_json_value_to_nu_value(v, span));
}
collected.into_spanned_value()
collected.into_tagged_value()
}
}
}
@@ -38,7 +38,7 @@ fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>)
pub fn from_json_string_to_value(
s: String,
span: impl Into<Span>,
) -> serde_hjson::Result<Spanned<Value>> {
) -> serde_hjson::Result<Tagged<Value>> {
let v: serde_hjson::Value = serde_hjson::from_str(&s)?;
Ok(convert_json_value_to_nu_value(&v, span))
}
@@ -48,20 +48,25 @@ pub fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span;
Ok(out
.values
.map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_json_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as JSON",
"piped data failed JSON parse",
.map(move |a| {
let value_span = a.span();
match a.item {
Value::Primitive(Primitive::String(s)) => {
match from_json_string_to_value(s, value_span) {
Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as JSON",
"piped data failed JSON parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
},
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}
})
.to_output_stream())
}

View File

@@ -1,34 +1,32 @@
use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spanned<Value> {
fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into();
match v {
toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).spanned(span),
toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).spanned(span),
toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).spanned(span),
toml::Value::String(s) => {
Value::Primitive(Primitive::String(String::from(s))).spanned(span)
}
toml::Value::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(span),
toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span),
toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(span),
toml::Value::Array(a) => Value::List(
a.iter()
.map(|x| convert_toml_value_to_nu_value(x, span))
.collect(),
)
.spanned(span),
.tagged(span),
toml::Value::Datetime(dt) => {
Value::Primitive(Primitive::String(dt.to_string())).spanned(span)
Value::Primitive(Primitive::String(dt.to_string())).tagged(span)
}
toml::Value::Table(t) => {
let mut collected = SpannedDictBuilder::new(span);
let mut collected = TaggedDictBuilder::new(span);
for (k, v) in t.iter() {
collected.insert_spanned(k.clone(), convert_toml_value_to_nu_value(v, span));
collected.insert_tagged(k.clone(), convert_toml_value_to_nu_value(v, span));
}
collected.into_spanned_value()
collected.into_tagged_value()
}
}
}
@@ -36,7 +34,7 @@ fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Spa
pub fn from_toml_string_to_value(
s: String,
span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> {
) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let v: toml::Value = s.parse::<toml::Value>()?;
Ok(convert_toml_value_to_nu_value(&v, span))
}
@@ -46,20 +44,25 @@ pub fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span;
Ok(out
.values
.map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_toml_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as TOML",
"piped data failed TOML parse",
.map(move |a| {
let value_span = a.span();
match a.item {
Value::Primitive(Primitive::String(s)) => {
match from_toml_string_to_value(s, value_span) {
Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as TOML",
"piped data failed TOML parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
},
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}
})
.to_output_stream())
}

View File

@@ -1,10 +1,7 @@
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
fn from_node_to_value<'a, 'd>(
n: &roxmltree::Node<'a, 'd>,
span: impl Into<Span>,
) -> Spanned<Value> {
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into();
if n.is_element() {
@@ -15,10 +12,10 @@ fn from_node_to_value<'a, 'd>(
children_values.push(from_node_to_value(&c, span));
}
let children_values: Vec<Spanned<Value>> = children_values
let children_values: Vec<Tagged<Value>> = children_values
.into_iter()
.filter(|x| match x {
Spanned {
Tagged {
item: Value::Primitive(Primitive::String(f)),
..
} => {
@@ -32,29 +29,29 @@ fn from_node_to_value<'a, 'd>(
})
.collect();
let mut collected = SpannedDictBuilder::new(span);
let mut collected = TaggedDictBuilder::new(span);
collected.insert(name.clone(), Value::List(children_values));
collected.into_spanned_value()
collected.into_tagged_value()
} else if n.is_comment() {
Value::string("<comment>").spanned(span)
Value::string("<comment>").tagged(span)
} else if n.is_pi() {
Value::string("<processing_instruction>").spanned(span)
Value::string("<processing_instruction>").tagged(span)
} else if n.is_text() {
Value::string(n.text().unwrap()).spanned(span)
Value::string(n.text().unwrap()).tagged(span)
} else {
Value::string("<unknown>").spanned(span)
Value::string("<unknown>").tagged(span)
}
}
fn from_document_to_value(d: &roxmltree::Document, span: impl Into<Span>) -> Spanned<Value> {
fn from_document_to_value(d: &roxmltree::Document, span: impl Into<Span>) -> Tagged<Value> {
from_node_to_value(&d.root_element(), span)
}
pub fn from_xml_string_to_value(
s: String,
span: impl Into<Span>,
) -> Result<Spanned<Value>, Box<dyn std::error::Error>> {
) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
let parsed = roxmltree::Document::parse(&s)?;
Ok(from_document_to_value(&parsed, span))
}
@@ -66,7 +63,7 @@ pub fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
.values
.map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_xml_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)),
Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as XML",
"piped data failed XML parse",

View File

@@ -1,41 +1,40 @@
use crate::object::base::OF64;
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>) -> Spanned<Value> {
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>) -> Tagged<Value> {
let span = span.into();
match v {
serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).spanned(span),
serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
serde_yaml::Value::Number(n) if n.is_i64() => {
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).spanned(span)
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(span)
}
serde_yaml::Value::Number(n) if n.is_f64() => {
Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).spanned(span)
Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(span)
}
serde_yaml::Value::String(s) => Value::string(s).spanned(span),
serde_yaml::Value::String(s) => Value::string(s).tagged(span),
serde_yaml::Value::Sequence(a) => Value::List(
a.iter()
.map(|x| convert_yaml_value_to_nu_value(x, span))
.collect(),
)
.spanned(span),
.tagged(span),
serde_yaml::Value::Mapping(t) => {
let mut collected = SpannedDictBuilder::new(span);
let mut collected = TaggedDictBuilder::new(span);
for (k, v) in t.iter() {
match k {
serde_yaml::Value::String(k) => {
collected
.insert_spanned(k.clone(), convert_yaml_value_to_nu_value(v, span));
collected.insert_tagged(k.clone(), convert_yaml_value_to_nu_value(v, span));
}
_ => unimplemented!("Unknown key type"),
}
}
collected.into_spanned_value()
collected.into_tagged_value()
}
serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).spanned(span),
serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).tagged(span),
x => unimplemented!("Unsupported yaml case: {:?}", x),
}
}
@@ -43,7 +42,7 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>)
pub fn from_yaml_string_to_value(
s: String,
span: impl Into<Span>,
) -> serde_yaml::Result<Spanned<Value>> {
) -> serde_yaml::Result<Tagged<Value>> {
let v: serde_yaml::Value = serde_yaml::from_str(&s)?;
Ok(convert_yaml_value_to_nu_value(&v, span))
}
@@ -53,20 +52,25 @@ pub fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
let span = args.call_info.name_span;
Ok(out
.values
.map(move |a| match a.item {
Value::Primitive(Primitive::String(s)) => match from_yaml_string_to_value(s, span) {
Ok(x) => ReturnSuccess::value(x.spanned(a.span)),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as YAML",
"piped data failed YAML parse",
.map(move |a| {
let value_span = a.span();
match a.item {
Value::Primitive(Primitive::String(s)) => {
match from_yaml_string_to_value(s, value_span) {
Ok(x) => ReturnSuccess::value(x),
Err(_) => Err(ShellError::maybe_labeled_error(
"Could not parse as YAML",
"piped data failed YAML parse",
span,
)),
}
}
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
},
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
span,
)),
}
})
.to_output_stream())
}

View File

@@ -1,9 +1,8 @@
use crate::errors::ShellError;
use crate::object::Value;
use crate::parser::Span;
use crate::prelude::*;
fn get_member(path: &str, span: Span, obj: &Spanned<Value>) -> Result<Spanned<Value>, ShellError> {
fn get_member(path: &str, span: Span, obj: &Tagged<Value>) -> Result<Tagged<Value>, ShellError> {
let mut current = obj;
for p in path.split(".") {
match current.get_data_by_key(p) {
@@ -44,7 +43,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let fields: Result<Vec<(String, Span)>, _> = args
.positional_iter()
.map(|a| (a.as_string().map(|x| (x, a.span))))
.map(|a| (a.as_string().map(|x| (x, a.span()))))
.collect();
let fields = fields?;
@@ -56,7 +55,7 @@ pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = VecDeque::new();
for field in &fields {
match get_member(&field.0, field.1, &item) {
Ok(Spanned {
Ok(Tagged {
item: Value::List(l),
..
}) => {

View File

@@ -20,7 +20,7 @@ pub fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = VecDeque::new();
for s in split_result {
result.push_back(ReturnSuccess::value(
Value::Primitive(Primitive::String(s.into())).spanned_unknown(),
Value::Primitive(Primitive::String(s.into())).tagged_unknown(),
));
}
result

View File

@@ -1,6 +1,5 @@
use crate::errors::ShellError;
use crate::object::{dir_entry_dict, Primitive, Value};
use crate::parser::Spanned;
use crate::prelude::*;
use std::path::{Path, PathBuf};
@@ -9,7 +8,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
let path = env.path.to_path_buf();
let mut full_path = PathBuf::from(path);
match &args.nth(0) {
Some(Spanned {
Some(Tagged {
item: Value::Primitive(Primitive::String(s)),
..
}) => full_path.push(Path::new(&s)),
@@ -24,7 +23,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
return Err(ShellError::labeled_error(
e.to_string(),
e.to_string(),
s.span,
s.span(),
));
} else {
return Err(ShellError::maybe_labeled_error(

View File

@@ -1,7 +1,6 @@
use crate::context::SpanSource;
use crate::errors::ShellError;
use crate::object::{Primitive, Switch, Value};
use crate::parser::parse::span::Span;
use crate::prelude::*;
use mime::Mime;
use std::path::{Path, PathBuf};
@@ -9,7 +8,7 @@ use std::str::FromStr;
use uuid::Uuid;
command! {
Open as open(args, path: Spanned<PathBuf>, --raw: Switch,) {
Open as open(args, path: Tagged<PathBuf>, --raw: Switch,) {
let span = args.call_info.name_span;
let cwd = args
@@ -21,9 +20,9 @@ command! {
let full_path = PathBuf::from(cwd);
let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".spanned(path.span)))?;
let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".tagged(path.span())))?;
let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span)?;
let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span())?;
let file_extension = if raw.is_present() {
None
@@ -48,7 +47,7 @@ command! {
)?;
match value {
Spanned { item: Value::List(list), .. } => {
Tagged { item: Value::List(list), .. } => {
for elem in list {
stream.push_back(ReturnSuccess::value(elem));
}
@@ -57,7 +56,7 @@ command! {
}
},
other => stream.push_back(ReturnSuccess::value(other.spanned(contents_span))),
other => stream.push_back(ReturnSuccess::value(other.tagged(contents_span))),
};
stream
@@ -206,11 +205,11 @@ pub fn parse_as_value(
contents: String,
contents_span: Span,
name_span: Option<Span>,
) -> Result<Spanned<Value>, ShellError> {
) -> Result<Tagged<Value>, ShellError> {
match extension {
Some(x) if x == "csv" => {
crate::commands::from_csv::from_csv_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span))
.map(|c| c.tagged(contents_span))
.map_err(move |_| {
ShellError::maybe_labeled_error(
"Could not open as CSV",
@@ -221,7 +220,7 @@ pub fn parse_as_value(
}
Some(x) if x == "toml" => {
crate::commands::from_toml::from_toml_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span))
.map(|c| c.tagged(contents_span))
.map_err(move |_| {
ShellError::maybe_labeled_error(
"Could not open as TOML",
@@ -232,7 +231,7 @@ pub fn parse_as_value(
}
Some(x) if x == "json" => {
crate::commands::from_json::from_json_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span))
.map(|c| c.tagged(contents_span))
.map_err(move |_| {
ShellError::maybe_labeled_error(
"Could not open as JSON",
@@ -243,7 +242,7 @@ pub fn parse_as_value(
}
Some(x) if x == "ini" => {
crate::commands::from_ini::from_ini_string_to_value(contents, contents_span)
.map(|c| c.spanned(contents_span))
.map(|c| c.tagged(contents_span))
.map_err(move |_| {
ShellError::maybe_labeled_error(
"Could not open as INI",
@@ -285,6 +284,6 @@ pub fn parse_as_value(
},
)
}
_ => Ok(Value::string(contents).spanned(contents_span)),
_ => Ok(Value::string(contents).tagged(contents_span)),
}
}

View File

@@ -17,7 +17,7 @@ pub fn pick(args: CommandArgs) -> Result<OutputStream, ShellError> {
let objects = input
.values
.map(move |value| select_fields(&value.item, &fields, value.span));
.map(move |value| select_fields(&value.item, &fields, value.span()));
Ok(objects.from_input_stream())
}

View File

@@ -78,11 +78,11 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
.spawn()
.expect("Failed to spawn child process");
let mut bos: VecDeque<Spanned<Value>> = VecDeque::new();
bos.push_back(Value::Primitive(Primitive::BeginningOfStream).spanned_unknown());
let mut bos: VecDeque<Tagged<Value>> = VecDeque::new();
bos.push_back(Value::Primitive(Primitive::BeginningOfStream).tagged_unknown());
let mut eos: VecDeque<Spanned<Value>> = VecDeque::new();
eos.push_back(Value::Primitive(Primitive::EndOfStream).spanned_unknown());
let mut eos: VecDeque<Tagged<Value>> = VecDeque::new();
eos.push_back(Value::Primitive(Primitive::EndOfStream).tagged_unknown());
let call_info = args.call_info;
@@ -90,7 +90,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
.chain(args.input.values)
.chain(eos)
.map(move |v| match v {
Spanned {
Tagged {
item: Value::Primitive(Primitive::BeginningOfStream),
..
} => {
@@ -136,7 +136,7 @@ pub fn filter_plugin(path: String, args: CommandArgs) -> Result<OutputStream, Sh
}
}
}
Spanned {
Tagged {
item: Value::Primitive(Primitive::EndOfStream),
..
} => {

View File

@@ -17,9 +17,9 @@ pub fn reject(args: CommandArgs) -> Result<OutputStream, ShellError> {
let fields = fields?;
let stream = args.input.values.map(move |item| {
reject_fields(&item, &fields, item.span)
.into_spanned_value()
.spanned(name_span)
reject_fields(&item, &fields, item.span())
.into_tagged_value()
.tagged(name_span)
});
Ok(stream.from_input_stream())

View File

@@ -5,7 +5,7 @@ use crate::commands::to_toml::value_to_toml_value;
use crate::commands::to_yaml::value_to_yaml_value;
use crate::errors::ShellError;
use crate::object::{Primitive, Value};
use crate::parser::Spanned;
use crate::Tagged;
use std::path::{Path, PathBuf};
pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
@@ -30,7 +30,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
}
let save_raw = match positional.get(1) {
Some(Spanned {
Some(Tagged {
item: Value::Primitive(Primitive::String(s)),
..
}) if s == "--raw" => true,

View File

@@ -1,5 +1,5 @@
use crate::errors::ShellError;
use crate::object::{SpannedDictBuilder, Value};
use crate::object::{TaggedDictBuilder, Value};
use crate::prelude::*;
pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
@@ -7,17 +7,17 @@ pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(input
.values
.map(move |v| match v.item {
Value::Primitive(Primitive::String(s)) => ReturnSuccess::value(count(&s, v.span)),
Value::Primitive(Primitive::String(ref s)) => ReturnSuccess::value(count(s, v.span())),
_ => Err(ShellError::maybe_labeled_error(
"Expected string values from pipeline",
"expects strings from pipeline",
Some(v.span),
Some(v.span()),
)),
})
.to_output_stream())
}
fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> {
fn count(contents: &str, span: impl Into<Span>) -> Tagged<Value> {
let mut lines: i64 = 0;
let mut words: i64 = 0;
let mut chars: i64 = 0;
@@ -42,7 +42,7 @@ fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> {
}
}
let mut dict = SpannedDictBuilder::new(span);
let mut dict = TaggedDictBuilder::new(span);
//TODO: add back in name when we have it in the span
//dict.insert("name", Value::string(name));
dict.insert("lines", Value::int(lines));
@@ -50,5 +50,5 @@ fn count(contents: &str, span: impl Into<Span>) -> Spanned<Value> {
dict.insert("chars", Value::int(chars));
dict.insert("max length", Value::int(bytes));
dict.into_spanned_value()
dict.into_tagged_value()
}

View File

@@ -12,7 +12,7 @@ pub fn sort_by(args: CommandArgs) -> Result<OutputStream, ShellError> {
fields
.iter()
.map(|f| item.get_data_by_key(f).map(|i| i.clone()))
.collect::<Vec<Option<Spanned<Value>>>>()
.collect::<Vec<Option<Tagged<Value>>>>()
});
vec.into_iter().collect::<VecDeque<_>>()

View File

@@ -1,5 +1,5 @@
use crate::errors::ShellError;
use crate::object::{Primitive, SpannedDictBuilder, Value};
use crate::object::{Primitive, TaggedDictBuilder, Value};
use crate::prelude::*;
use log::trace;
@@ -20,7 +20,7 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
Ok(input
.values
.map(move |v| match v.item {
Value::Primitive(Primitive::String(s)) => {
Value::Primitive(Primitive::String(ref s)) => {
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n");
trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
@@ -34,27 +34,27 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
gen_columns.push(format!("Column{}", i + 1));
}
let mut dict = SpannedDictBuilder::new(v.span);
let mut dict = TaggedDictBuilder::new(v.span());
for (&k, v) in split_result.iter().zip(gen_columns.iter()) {
dict.insert(v.clone(), Primitive::String(k.into()));
}
ReturnSuccess::value(dict.into_spanned_value())
ReturnSuccess::value(dict.into_tagged_value())
} else if split_result.len() == (positional.len() - 1) {
let mut dict = SpannedDictBuilder::new(v.span);
let mut dict = TaggedDictBuilder::new(v.span());
for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) {
dict.insert(
v.as_string().unwrap(),
Value::Primitive(Primitive::String(k.into())),
);
}
ReturnSuccess::value(dict.into_spanned_value())
ReturnSuccess::value(dict.into_tagged_value())
} else {
let mut dict = SpannedDictBuilder::new(v.span);
let mut dict = TaggedDictBuilder::new(v.span());
for k in positional.iter().skip(1) {
dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into()));
}
ReturnSuccess::value(dict.into_spanned_value())
ReturnSuccess::value(dict.into_tagged_value())
}
}
_ => Err(ShellError::maybe_labeled_error(

View File

@@ -1,11 +1,10 @@
use crate::errors::ShellError;
use crate::object::{Primitive, Value};
use crate::parser::Spanned;
use crate::prelude::*;
use log::trace;
pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
let positional: Vec<Spanned<Value>> = args.positional_iter().cloned().collect();
let positional: Vec<Tagged<Value>> = args.positional_iter().cloned().collect();
let span = args.call_info.name_span;
if positional.len() == 0 {
@@ -21,7 +20,7 @@ pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
let stream = input
.values
.map(move |v| match v.item {
Value::Primitive(Primitive::String(s)) => {
Value::Primitive(Primitive::String(ref s)) => {
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n");
trace!("splitting with {:?}", splitter);
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
@@ -31,7 +30,7 @@ pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
let mut result = VecDeque::new();
for s in split_result {
result.push_back(ReturnSuccess::value(
Value::Primitive(Primitive::String(s.into())).spanned(v.span),
Value::Primitive(Primitive::String(s.into())).tagged(v.span()),
));
}
result

View File

@@ -5,7 +5,7 @@ pub fn to_array(args: CommandArgs) -> Result<OutputStream, ShellError> {
let out = args.input.values.collect();
Ok(out
.map(|vec: Vec<_>| stream![Value::List(vec).spanned_unknown()]) // TODO: args.input should have a span
.map(|vec: Vec<_>| stream![Value::List(vec).tagged_unknown()]) // TODO: args.input should have a span
.flatten_stream()
.from_input_stream())
}

View File

@@ -9,7 +9,7 @@ pub fn value_to_csv_value(v: &Value) -> Value {
Value::Object(o) => Value::Object(o.clone()),
Value::List(l) => Value::List(l.clone()),
Value::Block(_) => Value::Primitive(Primitive::Nothing),
_ => Value::Primitive(Primitive::Nothing)
_ => Value::Primitive(Primitive::Nothing),
}
}
@@ -25,14 +25,14 @@ pub fn to_string(v: &Value) -> Result<String, Box<dyn std::error::Error>> {
fields.push_back(k.clone());
values.push_back(to_string(&v)?);
}
wtr.write_record(fields).expect("can not write.");
wtr.write_record(values).expect("can not write.");
return Ok(String::from_utf8(wtr.into_inner()?)?)
},
return Ok(String::from_utf8(wtr.into_inner()?)?);
}
Value::Primitive(Primitive::String(s)) => return Ok(s.to_string()),
_ => return Err("Bad input".into())
_ => return Err("Bad input".into()),
}
}
@@ -41,18 +41,13 @@ pub fn to_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
let name_span = args.call_info.name_span;
Ok(out
.values
.map(
move |a| match to_string(&value_to_csv_value(&a.item)) {
Ok(x) => {
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span))
}
Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to CSV string",
"can not convert piped data to CSV string",
name_span,
)),
},
)
.map(move |a| match to_string(&value_to_csv_value(&a.item)) {
Ok(x) => ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span)),
Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to CSV string",
"can not convert piped data to CSV string",
name_span,
)),
})
.to_output_stream())
}

View File

@@ -49,7 +49,7 @@ pub fn to_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map(
move |a| match serde_json::to_string(&value_to_json_value(&a)) {
Ok(x) => {
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span))
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span))
}
Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to JSON string",

View File

@@ -42,13 +42,13 @@ pub fn to_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map(move |a| match toml::to_string(&value_to_toml_value(&a)) {
Ok(val) => {
return ReturnSuccess::value(
Value::Primitive(Primitive::String(val)).spanned(name_span),
Value::Primitive(Primitive::String(val)).tagged(name_span),
)
}
Err(err) => Err(ShellError::type_error(
"Can not convert to a TOML string",
format!("{:?} - {:?}", a.type_name(), err).spanned(name_span),
format!("{:?} - {:?}", a.type_name(), err).tagged(name_span),
)),
})
.to_output_stream())

View File

@@ -47,7 +47,7 @@ pub fn to_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
.map(
move |a| match serde_yaml::to_string(&value_to_yaml_value(&a)) {
Ok(x) => {
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).spanned(name_span))
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span))
}
Err(_) => Err(ShellError::maybe_labeled_error(
"Can not convert to YAML string",

View File

@@ -9,7 +9,7 @@ pub fn trim(args: CommandArgs) -> Result<OutputStream, ShellError> {
.values
.map(move |v| {
let string = String::extract(&v)?;
ReturnSuccess::value(Value::string(string.trim()).spanned(v.span))
ReturnSuccess::value(Value::string(string.trim()).tagged(v.span()))
})
.to_output_stream())
}