mirror of
https://github.com/nushell/nushell.git
synced 2025-08-17 23:19:49 +02:00
Move more parts to tags and away from spans
This commit is contained in:
@@ -10,7 +10,7 @@ pub fn cd(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
None => match dirs::home_dir() {
|
||||
Some(o) => o,
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Can not change to home directory",
|
||||
"can not go to home",
|
||||
args.call_info.name_span,
|
||||
|
@@ -99,7 +99,7 @@ impl ClassifiedCommand {
|
||||
|
||||
crate struct SinkCommand {
|
||||
crate command: Arc<dyn Sink>,
|
||||
crate name_span: Option<Span>,
|
||||
crate name_span: Span,
|
||||
crate args: Args,
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ impl SinkCommand {
|
||||
|
||||
crate struct InternalCommand {
|
||||
crate command: Arc<dyn Command>,
|
||||
crate name_span: Option<Span>,
|
||||
crate name_span: Span,
|
||||
crate args: Args,
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ impl InternalCommand {
|
||||
crate struct ExternalCommand {
|
||||
crate name: String,
|
||||
#[allow(unused)]
|
||||
crate name_span: Option<Span>,
|
||||
crate name_span: Span,
|
||||
crate args: Vec<Tagged<String>>,
|
||||
}
|
||||
|
||||
@@ -240,7 +240,10 @@ impl ExternalCommand {
|
||||
} else {
|
||||
for arg in &self.args {
|
||||
let arg_chars: Vec<_> = arg.chars().collect();
|
||||
if arg_chars.len() > 1 && arg_chars[0] == '"' && arg_chars[arg_chars.len() - 1] == '"' {
|
||||
if arg_chars.len() > 1
|
||||
&& arg_chars[0] == '"'
|
||||
&& arg_chars[arg_chars.len() - 1] == '"'
|
||||
{
|
||||
// quoted string
|
||||
let new_arg: String = arg_chars[1..arg_chars.len() - 1].iter().collect();
|
||||
process = process.arg(new_arg);
|
||||
@@ -258,13 +261,13 @@ impl ExternalCommand {
|
||||
let mut first = true;
|
||||
for i in &inputs {
|
||||
if i.as_string().is_err() {
|
||||
let mut span = None;
|
||||
let mut span = name_span;
|
||||
for arg in &self.args {
|
||||
if arg.item.contains("$it") {
|
||||
span = Some(arg.span());
|
||||
span = arg.span();
|
||||
}
|
||||
}
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"External $it needs string data",
|
||||
"given object instead of string data",
|
||||
span,
|
||||
@@ -323,7 +326,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()).tagged(name_span));
|
||||
let stream = stream.map(move |line| {
|
||||
Tagged::from_simple_spanned_item(Value::string(line.unwrap()), name_span)
|
||||
});
|
||||
Ok(ClassifiedInputStream::from_input_stream(
|
||||
stream.boxed() as BoxStream<'static, Tagged<Value>>
|
||||
))
|
||||
|
@@ -13,7 +13,7 @@ use uuid::Uuid;
|
||||
pub struct CallInfo {
|
||||
pub args: Args,
|
||||
pub source_map: SourceMap,
|
||||
pub name_span: Option<Span>,
|
||||
pub name_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Getters)]
|
||||
@@ -93,7 +93,9 @@ impl ReturnSuccess {
|
||||
}
|
||||
|
||||
pub fn spanned_value(input: Value, span: Span) -> ReturnValue {
|
||||
Ok(ReturnSuccess::Value(Tagged::from_item(input, span)))
|
||||
Ok(ReturnSuccess::Value(Tagged::from_simple_spanned_item(
|
||||
input, span,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -61,10 +61,11 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
|
||||
config::write_config(&result)?;
|
||||
|
||||
return Ok(
|
||||
stream![Tagged::from_item(Value::Object(result.into()), v.span())]
|
||||
.from_input_stream(),
|
||||
);
|
||||
return Ok(stream![Tagged::from_simple_spanned_item(
|
||||
Value::Object(result.into()),
|
||||
v.span()
|
||||
)]
|
||||
.from_input_stream());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,9 +74,11 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
|
||||
config::write_config(&result)?;
|
||||
|
||||
return Ok(
|
||||
stream![Tagged::from_item(Value::Object(result.into()), c.span())].from_input_stream(),
|
||||
);
|
||||
return Ok(stream![Tagged::from_simple_spanned_item(
|
||||
Value::Object(result.into()),
|
||||
c.span()
|
||||
)]
|
||||
.from_input_stream());
|
||||
}
|
||||
|
||||
if let Some(v) = args.get("remove") {
|
||||
@@ -90,12 +93,14 @@ pub fn config(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
)));
|
||||
}
|
||||
|
||||
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).tagged(v)]);
|
||||
let obj = VecDeque::from_iter(vec![Value::Object(result.into()).simple_spanned(v)]);
|
||||
return Ok(obj.from_input_stream());
|
||||
}
|
||||
|
||||
if args.len() == 0 {
|
||||
return Ok(vec![Value::Object(result.into()).tagged(args.call_info.name_span)].into());
|
||||
return Ok(
|
||||
vec![Value::Object(result.into()).simple_spanned(args.call_info.name_span)].into(),
|
||||
);
|
||||
}
|
||||
|
||||
Err(ShellError::string(format!("Unimplemented")))
|
||||
|
@@ -42,41 +42,41 @@ where
|
||||
|
||||
indexmap.insert(
|
||||
"year".to_string(),
|
||||
Tagged::from_item(Value::int(dt.year()), span),
|
||||
Tagged::from_simple_spanned_item(Value::int(dt.year()), span),
|
||||
);
|
||||
indexmap.insert(
|
||||
"month".to_string(),
|
||||
Tagged::from_item(Value::int(dt.month()), span),
|
||||
Tagged::from_simple_spanned_item(Value::int(dt.month()), span),
|
||||
);
|
||||
indexmap.insert(
|
||||
"day".to_string(),
|
||||
Tagged::from_item(Value::int(dt.day()), span),
|
||||
Tagged::from_simple_spanned_item(Value::int(dt.day()), span),
|
||||
);
|
||||
indexmap.insert(
|
||||
"hour".to_string(),
|
||||
Tagged::from_item(Value::int(dt.hour()), span),
|
||||
Tagged::from_simple_spanned_item(Value::int(dt.hour()), span),
|
||||
);
|
||||
indexmap.insert(
|
||||
"minute".to_string(),
|
||||
Tagged::from_item(Value::int(dt.minute()), span),
|
||||
Tagged::from_simple_spanned_item(Value::int(dt.minute()), span),
|
||||
);
|
||||
indexmap.insert(
|
||||
"second".to_string(),
|
||||
Tagged::from_item(Value::int(dt.second()), span),
|
||||
Tagged::from_simple_spanned_item(Value::int(dt.second()), span),
|
||||
);
|
||||
|
||||
let tz = dt.offset();
|
||||
indexmap.insert(
|
||||
"timezone".to_string(),
|
||||
Tagged::from_item(Value::string(format!("{}", tz)), span),
|
||||
Tagged::from_simple_spanned_item(Value::string(format!("{}", tz)), span),
|
||||
);
|
||||
|
||||
Tagged::from_item(Value::Object(Dictionary::from(indexmap)), span)
|
||||
Tagged::from_simple_spanned_item(Value::Object(Dictionary::from(indexmap)), span)
|
||||
}
|
||||
|
||||
pub fn date(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let mut date_out = VecDeque::new();
|
||||
let span = args.call_info.name_span.unwrap();
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
let value = if args.has("utc") {
|
||||
let utc: DateTime<Utc> = Utc::now();
|
||||
|
@@ -5,7 +5,7 @@ use crate::prelude::*;
|
||||
|
||||
pub fn first(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"First requires an amount",
|
||||
"needs parameter",
|
||||
args.call_info.name_span,
|
||||
|
@@ -4,12 +4,12 @@ use csv::ReaderBuilder;
|
||||
|
||||
pub fn from_csv_string_to_value(
|
||||
s: String,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
|
||||
let mut reader = ReaderBuilder::new()
|
||||
.has_headers(false)
|
||||
.from_reader(s.as_bytes());
|
||||
let span = span.into();
|
||||
let tag = tag.into();
|
||||
|
||||
let mut fields: VecDeque<String> = VecDeque::new();
|
||||
let mut iter = reader.records();
|
||||
@@ -27,12 +27,12 @@ pub fn from_csv_string_to_value(
|
||||
if let Some(row_values) = iter.next() {
|
||||
let row_values = row_values?;
|
||||
|
||||
let mut row = TaggedDictBuilder::new(span);
|
||||
let mut row = TaggedDictBuilder::new(tag);
|
||||
|
||||
for (idx, entry) in row_values.iter().enumerate() {
|
||||
row.insert_tagged(
|
||||
fields.get(idx).unwrap(),
|
||||
Value::Primitive(Primitive::String(String::from(entry))).tagged(span),
|
||||
Value::Primitive(Primitive::String(String::from(entry))).tagged(tag),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ pub fn from_csv_string_to_value(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Tagged::from_item(Value::List(rows), span))
|
||||
Ok(Tagged::from_item(Value::List(rows), tag))
|
||||
}
|
||||
|
||||
pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
@@ -52,22 +52,26 @@ pub fn from_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| {
|
||||
let value_span = a.span();
|
||||
let value_tag = a.tag();
|
||||
match a.item {
|
||||
Value::Primitive(Primitive::String(s)) => {
|
||||
match from_csv_string_to_value(s, value_span) {
|
||||
match from_csv_string_to_value(s, value_tag) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Err(_) => Err(ShellError::labeled_error_with_secondary(
|
||||
"Could not parse as CSV",
|
||||
"piped data failed CSV parse",
|
||||
"input cannot be parsed as CSV",
|
||||
span,
|
||||
"value originates from here",
|
||||
value_tag.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
a.span(),
|
||||
)),
|
||||
}
|
||||
})
|
||||
|
@@ -4,9 +4,9 @@ use std::collections::HashMap;
|
||||
|
||||
fn convert_ini_second_to_nu_value(
|
||||
v: &HashMap<String, String>,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> Tagged<Value> {
|
||||
let mut second = TaggedDictBuilder::new(span);
|
||||
let mut second = TaggedDictBuilder::new(tag);
|
||||
|
||||
for (key, value) in v.into_iter() {
|
||||
second.insert(key.clone(), Primitive::String(value.clone()));
|
||||
@@ -17,13 +17,13 @@ fn convert_ini_second_to_nu_value(
|
||||
|
||||
fn convert_ini_top_to_nu_value(
|
||||
v: &HashMap<String, HashMap<String, String>>,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> Tagged<Value> {
|
||||
let span = span.into();
|
||||
let mut top_level = TaggedDictBuilder::new(span);
|
||||
let tag = tag.into();
|
||||
let mut top_level = TaggedDictBuilder::new(tag);
|
||||
|
||||
for (key, value) in v.iter() {
|
||||
top_level.insert_tagged(key.clone(), convert_ini_second_to_nu_value(value, span));
|
||||
top_level.insert_tagged(key.clone(), convert_ini_second_to_nu_value(value, tag));
|
||||
}
|
||||
|
||||
top_level.into_tagged_value()
|
||||
@@ -31,10 +31,10 @@ fn convert_ini_top_to_nu_value(
|
||||
|
||||
pub fn from_ini_string_to_value(
|
||||
s: String,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> 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))
|
||||
Ok(convert_ini_top_to_nu_value(&v, tag))
|
||||
}
|
||||
|
||||
pub fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
@@ -43,22 +43,26 @@ pub fn from_ini(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| {
|
||||
let value_span = a.span();
|
||||
let value_tag = a.tag();
|
||||
match a.item {
|
||||
Value::Primitive(Primitive::String(s)) => {
|
||||
match from_ini_string_to_value(s, value_span) {
|
||||
match from_ini_string_to_value(s, value_tag) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Err(_) => Err(ShellError::labeled_error_with_secondary(
|
||||
"Could not parse as INI",
|
||||
"piped data failed INI parse",
|
||||
"input cannot be parsed as INI",
|
||||
span,
|
||||
"value originates from here",
|
||||
value_tag.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
a.span(),
|
||||
)),
|
||||
}
|
||||
})
|
||||
|
@@ -2,32 +2,32 @@ use crate::object::base::OF64;
|
||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||
use crate::prelude::*;
|
||||
|
||||
fn convert_json_value_to_nu_value(v: &serde_hjson::Value, span: impl Into<Span>) -> Tagged<Value> {
|
||||
let span = span.into();
|
||||
fn convert_json_value_to_nu_value(v: &serde_hjson::Value, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||
let tag = tag.into();
|
||||
|
||||
match v {
|
||||
serde_hjson::Value::Null => {
|
||||
Value::Primitive(Primitive::String(String::from(""))).tagged(span)
|
||||
Value::Primitive(Primitive::String(String::from(""))).tagged(tag)
|
||||
}
|
||||
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
|
||||
serde_hjson::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
||||
serde_hjson::Value::F64(n) => {
|
||||
Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(span)
|
||||
Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag)
|
||||
}
|
||||
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::U64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag),
|
||||
serde_hjson::Value::I64(n) => Value::Primitive(Primitive::Int(*n as i64)).tagged(tag),
|
||||
serde_hjson::Value::String(s) => {
|
||||
Value::Primitive(Primitive::String(String::from(s))).tagged(span)
|
||||
Value::Primitive(Primitive::String(String::from(s))).tagged(tag)
|
||||
}
|
||||
serde_hjson::Value::Array(a) => Value::List(
|
||||
a.iter()
|
||||
.map(|x| convert_json_value_to_nu_value(x, span))
|
||||
.map(|x| convert_json_value_to_nu_value(x, tag))
|
||||
.collect(),
|
||||
)
|
||||
.tagged(span),
|
||||
.tagged(tag),
|
||||
serde_hjson::Value::Object(o) => {
|
||||
let mut collected = TaggedDictBuilder::new(span);
|
||||
let mut collected = TaggedDictBuilder::new(tag);
|
||||
for (k, v) in o.iter() {
|
||||
collected.insert_tagged(k.clone(), convert_json_value_to_nu_value(v, span));
|
||||
collected.insert_tagged(k.clone(), convert_json_value_to_nu_value(v, tag));
|
||||
}
|
||||
|
||||
collected.into_tagged_value()
|
||||
@@ -37,10 +37,10 @@ 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>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> serde_hjson::Result<Tagged<Value>> {
|
||||
let v: serde_hjson::Value = serde_hjson::from_str(&s)?;
|
||||
Ok(convert_json_value_to_nu_value(&v, span))
|
||||
Ok(convert_json_value_to_nu_value(&v, tag))
|
||||
}
|
||||
|
||||
pub fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
@@ -49,22 +49,26 @@ pub fn from_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| {
|
||||
let value_span = a.span();
|
||||
let value_tag = a.tag();
|
||||
match a.item {
|
||||
Value::Primitive(Primitive::String(s)) => {
|
||||
match from_json_string_to_value(s, value_span) {
|
||||
match from_json_string_to_value(s, value_tag) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Err(_) => Err(ShellError::labeled_error_with_secondary(
|
||||
"Could not parse as JSON",
|
||||
"piped data failed JSON parse",
|
||||
"input cannot be parsed as JSON",
|
||||
span,
|
||||
"value originates from here",
|
||||
value_tag.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
a.span(),
|
||||
)),
|
||||
}
|
||||
})
|
||||
|
@@ -2,28 +2,28 @@ use crate::object::base::OF64;
|
||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||
use crate::prelude::*;
|
||||
|
||||
fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Tagged<Value> {
|
||||
let span = span.into();
|
||||
fn convert_toml_value_to_nu_value(v: &toml::Value, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||
let tag = tag.into();
|
||||
|
||||
match v {
|
||||
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::Boolean(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
||||
toml::Value::Integer(n) => Value::Primitive(Primitive::Int(*n)).tagged(tag),
|
||||
toml::Value::Float(n) => Value::Primitive(Primitive::Float(OF64::from(*n))).tagged(tag),
|
||||
toml::Value::String(s) => Value::Primitive(Primitive::String(String::from(s))).tagged(tag),
|
||||
toml::Value::Array(a) => Value::List(
|
||||
a.iter()
|
||||
.map(|x| convert_toml_value_to_nu_value(x, span))
|
||||
.map(|x| convert_toml_value_to_nu_value(x, tag))
|
||||
.collect(),
|
||||
)
|
||||
.tagged(span),
|
||||
.tagged(tag),
|
||||
toml::Value::Datetime(dt) => {
|
||||
Value::Primitive(Primitive::String(dt.to_string())).tagged(span)
|
||||
Value::Primitive(Primitive::String(dt.to_string())).tagged(tag)
|
||||
}
|
||||
toml::Value::Table(t) => {
|
||||
let mut collected = TaggedDictBuilder::new(span);
|
||||
let mut collected = TaggedDictBuilder::new(tag);
|
||||
|
||||
for (k, v) in t.iter() {
|
||||
collected.insert_tagged(k.clone(), convert_toml_value_to_nu_value(v, span));
|
||||
collected.insert_tagged(k.clone(), convert_toml_value_to_nu_value(v, tag));
|
||||
}
|
||||
|
||||
collected.into_tagged_value()
|
||||
@@ -33,10 +33,10 @@ fn convert_toml_value_to_nu_value(v: &toml::Value, span: impl Into<Span>) -> Tag
|
||||
|
||||
pub fn from_toml_string_to_value(
|
||||
s: String,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> 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))
|
||||
Ok(convert_toml_value_to_nu_value(&v, tag))
|
||||
}
|
||||
|
||||
pub fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
@@ -45,22 +45,26 @@ pub fn from_toml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| {
|
||||
let value_span = a.span();
|
||||
let value_tag = a.tag();
|
||||
match a.item {
|
||||
Value::Primitive(Primitive::String(s)) => {
|
||||
match from_toml_string_to_value(s, value_span) {
|
||||
match from_toml_string_to_value(s, value_tag) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Err(_) => Err(ShellError::labeled_error_with_secondary(
|
||||
"Could not parse as TOML",
|
||||
"piped data failed TOML parse",
|
||||
"input cannot be parsed as TOML",
|
||||
span,
|
||||
"value originates from here",
|
||||
value_tag.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
a.span(),
|
||||
)),
|
||||
}
|
||||
})
|
||||
|
@@ -1,15 +1,15 @@
|
||||
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>) -> Tagged<Value> {
|
||||
let span = span.into();
|
||||
fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||
let tag = tag.into();
|
||||
|
||||
if n.is_element() {
|
||||
let name = n.tag_name().name().trim().to_string();
|
||||
|
||||
let mut children_values = vec![];
|
||||
for c in n.children() {
|
||||
children_values.push(from_node_to_value(&c, span));
|
||||
children_values.push(from_node_to_value(&c, tag));
|
||||
}
|
||||
|
||||
let children_values: Vec<Tagged<Value>> = children_values
|
||||
@@ -29,31 +29,31 @@ fn from_node_to_value<'a, 'd>(n: &roxmltree::Node<'a, 'd>, span: impl Into<Span>
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut collected = TaggedDictBuilder::new(span);
|
||||
let mut collected = TaggedDictBuilder::new(tag);
|
||||
collected.insert(name.clone(), Value::List(children_values));
|
||||
|
||||
collected.into_tagged_value()
|
||||
} else if n.is_comment() {
|
||||
Value::string("<comment>").tagged(span)
|
||||
Value::string("<comment>").tagged(tag)
|
||||
} else if n.is_pi() {
|
||||
Value::string("<processing_instruction>").tagged(span)
|
||||
Value::string("<processing_instruction>").tagged(tag)
|
||||
} else if n.is_text() {
|
||||
Value::string(n.text().unwrap()).tagged(span)
|
||||
Value::string(n.text().unwrap()).tagged(tag)
|
||||
} else {
|
||||
Value::string("<unknown>").tagged(span)
|
||||
Value::string("<unknown>").tagged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
fn from_document_to_value(d: &roxmltree::Document, span: impl Into<Span>) -> Tagged<Value> {
|
||||
from_node_to_value(&d.root_element(), span)
|
||||
fn from_document_to_value(d: &roxmltree::Document, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||
from_node_to_value(&d.root_element(), tag)
|
||||
}
|
||||
|
||||
pub fn from_xml_string_to_value(
|
||||
s: String,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> Result<Tagged<Value>, Box<dyn std::error::Error>> {
|
||||
let parsed = roxmltree::Document::parse(&s)?;
|
||||
Ok(from_document_to_value(&parsed, span))
|
||||
Ok(from_document_to_value(&parsed, tag))
|
||||
}
|
||||
|
||||
pub fn from_xml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
@@ -61,20 +61,29 @@ pub fn from_xml(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_xml_string_to_value(s, span) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
"Could not parse as XML",
|
||||
"piped data failed XML parse",
|
||||
.map(move |a| {
|
||||
let value_tag = a.tag();
|
||||
match a.item {
|
||||
Value::Primitive(Primitive::String(s)) => {
|
||||
match from_xml_string_to_value(s, value_tag) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::labeled_error_with_secondary(
|
||||
"Could not parse as XML",
|
||||
"input cannot be parsed as XML",
|
||||
span,
|
||||
"value originates from here",
|
||||
value_tag.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
a.span(),
|
||||
)),
|
||||
},
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
span,
|
||||
)),
|
||||
}
|
||||
})
|
||||
.to_output_stream())
|
||||
}
|
||||
|
@@ -2,31 +2,31 @@ use crate::object::base::OF64;
|
||||
use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||
use crate::prelude::*;
|
||||
|
||||
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>) -> Tagged<Value> {
|
||||
let span = span.into();
|
||||
fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||
let tag = tag.into();
|
||||
|
||||
match v {
|
||||
serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(span),
|
||||
serde_yaml::Value::Bool(b) => Value::Primitive(Primitive::Boolean(*b)).tagged(tag),
|
||||
serde_yaml::Value::Number(n) if n.is_i64() => {
|
||||
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(span)
|
||||
Value::Primitive(Primitive::Int(n.as_i64().unwrap())).tagged(tag)
|
||||
}
|
||||
serde_yaml::Value::Number(n) if n.is_f64() => {
|
||||
Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(span)
|
||||
Value::Primitive(Primitive::Float(OF64::from(n.as_f64().unwrap()))).tagged(tag)
|
||||
}
|
||||
serde_yaml::Value::String(s) => Value::string(s).tagged(span),
|
||||
serde_yaml::Value::String(s) => Value::string(s).tagged(tag),
|
||||
serde_yaml::Value::Sequence(a) => Value::List(
|
||||
a.iter()
|
||||
.map(|x| convert_yaml_value_to_nu_value(x, span))
|
||||
.map(|x| convert_yaml_value_to_nu_value(x, tag))
|
||||
.collect(),
|
||||
)
|
||||
.tagged(span),
|
||||
.tagged(tag),
|
||||
serde_yaml::Value::Mapping(t) => {
|
||||
let mut collected = TaggedDictBuilder::new(span);
|
||||
let mut collected = TaggedDictBuilder::new(tag);
|
||||
|
||||
for (k, v) in t.iter() {
|
||||
match k {
|
||||
serde_yaml::Value::String(k) => {
|
||||
collected.insert_tagged(k.clone(), convert_yaml_value_to_nu_value(v, span));
|
||||
collected.insert_tagged(k.clone(), convert_yaml_value_to_nu_value(v, tag));
|
||||
}
|
||||
_ => unimplemented!("Unknown key type"),
|
||||
}
|
||||
@@ -34,17 +34,17 @@ fn convert_yaml_value_to_nu_value(v: &serde_yaml::Value, span: impl Into<Span>)
|
||||
|
||||
collected.into_tagged_value()
|
||||
}
|
||||
serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).tagged(span),
|
||||
serde_yaml::Value::Null => Value::Primitive(Primitive::Nothing).tagged(tag),
|
||||
x => unimplemented!("Unsupported yaml case: {:?}", x),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_yaml_string_to_value(
|
||||
s: String,
|
||||
span: impl Into<Span>,
|
||||
tag: impl Into<Tag>,
|
||||
) -> serde_yaml::Result<Tagged<Value>> {
|
||||
let v: serde_yaml::Value = serde_yaml::from_str(&s)?;
|
||||
Ok(convert_yaml_value_to_nu_value(&v, span))
|
||||
Ok(convert_yaml_value_to_nu_value(&v, tag))
|
||||
}
|
||||
|
||||
pub fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
@@ -53,22 +53,26 @@ pub fn from_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(out
|
||||
.values
|
||||
.map(move |a| {
|
||||
let value_span = a.span();
|
||||
let value_tag = a.tag();
|
||||
match a.item {
|
||||
Value::Primitive(Primitive::String(s)) => {
|
||||
match from_yaml_string_to_value(s, value_span) {
|
||||
match from_yaml_string_to_value(s, value_tag) {
|
||||
Ok(x) => ReturnSuccess::value(x),
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Err(_) => Err(ShellError::labeled_error_with_secondary(
|
||||
"Could not parse as YAML",
|
||||
"piped data failed YAML parse",
|
||||
"input cannot be parsed as YAML",
|
||||
span,
|
||||
"value originates from here",
|
||||
value_tag.span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
a.span(),
|
||||
)),
|
||||
}
|
||||
})
|
||||
|
@@ -22,7 +22,7 @@ fn get_member(path: &str, span: Span, obj: &Tagged<Value>) -> Result<Tagged<Valu
|
||||
|
||||
pub fn get(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Get requires a field or field path",
|
||||
"needs parameter",
|
||||
args.call_info.name_span,
|
||||
|
@@ -27,10 +27,12 @@ pub fn lines(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
}
|
||||
_ => {
|
||||
let mut result = VecDeque::new();
|
||||
result.push_back(Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
result.push_back(Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
v.span(),
|
||||
)));
|
||||
result
|
||||
}
|
||||
|
@@ -37,7 +37,7 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
s.span(),
|
||||
));
|
||||
} else {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
args.call_info.name_span,
|
||||
@@ -50,8 +50,11 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let entry = entry?;
|
||||
let filepath = entry.path();
|
||||
let filename = filepath.strip_prefix(&cwd).unwrap();
|
||||
let value =
|
||||
dir_entry_dict(filename, &entry.metadata()?, args.call_info.name_span)?;
|
||||
let value = dir_entry_dict(
|
||||
filename,
|
||||
&entry.metadata()?,
|
||||
Tag::unknown_origin(args.call_info.name_span),
|
||||
)?;
|
||||
shell_entries.push_back(ReturnSuccess::value(value))
|
||||
}
|
||||
return Ok(shell_entries.to_output_stream());
|
||||
@@ -64,7 +67,11 @@ pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if let Ok(entry) = entry {
|
||||
let filename = entry.strip_prefix(&cwd).unwrap();
|
||||
let metadata = std::fs::metadata(&entry)?;
|
||||
let value = dir_entry_dict(filename, &metadata, args.call_info.name_span)?;
|
||||
let value = dir_entry_dict(
|
||||
filename,
|
||||
&metadata,
|
||||
Tag::unknown_origin(args.call_info.name_span),
|
||||
)?;
|
||||
shell_entries.push_back(ReturnSuccess::value(value))
|
||||
}
|
||||
}
|
||||
|
@@ -20,9 +20,9 @@ command! {
|
||||
|
||||
let full_path = PathBuf::from(cwd);
|
||||
|
||||
let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".tagged(path.span())))?;
|
||||
let path_str = path.to_str().ok_or(ShellError::type_error("Path", "invalid path".simple_spanned(path.span())))?;
|
||||
|
||||
let (file_extension, contents, contents_span, span_source) = fetch(&full_path, path_str, path.span())?;
|
||||
let (file_extension, contents, contents_tag, span_source) = fetch(&full_path, path_str, path.span())?;
|
||||
|
||||
let file_extension = if raw.is_present() {
|
||||
None
|
||||
@@ -32,7 +32,7 @@ command! {
|
||||
|
||||
let mut stream = VecDeque::new();
|
||||
|
||||
if let Some(uuid) = contents_span.source {
|
||||
if let Some(uuid) = contents_tag.origin {
|
||||
// If we have loaded something, track its source
|
||||
stream.push_back(ReturnSuccess::action(CommandAction::AddSpanSource(uuid, span_source)))
|
||||
}
|
||||
@@ -42,7 +42,7 @@ command! {
|
||||
let value = parse_as_value(
|
||||
file_extension,
|
||||
string,
|
||||
contents_span,
|
||||
contents_tag,
|
||||
span,
|
||||
)?;
|
||||
|
||||
@@ -56,7 +56,7 @@ command! {
|
||||
}
|
||||
},
|
||||
|
||||
other => stream.push_back(ReturnSuccess::value(other.tagged(contents_span))),
|
||||
other => stream.push_back(ReturnSuccess::value(other.tagged(contents_tag))),
|
||||
};
|
||||
|
||||
stream
|
||||
@@ -67,7 +67,7 @@ pub fn fetch(
|
||||
cwd: &PathBuf,
|
||||
location: &str,
|
||||
span: Span,
|
||||
) -> Result<(Option<String>, Value, Span, SpanSource), ShellError> {
|
||||
) -> Result<(Option<String>, Value, Tag, SpanSource), ShellError> {
|
||||
let mut cwd = cwd.clone();
|
||||
if location.starts_with("http:") || location.starts_with("https:") {
|
||||
let response = reqwest::get(location);
|
||||
@@ -79,13 +79,19 @@ pub fn fetch(
|
||||
(mime::APPLICATION, mime::XML) => Ok((
|
||||
Some("xml".to_string()),
|
||||
Value::string(r.text().unwrap()),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
(mime::APPLICATION, mime::JSON) => Ok((
|
||||
Some("json".to_string()),
|
||||
Value::string(r.text().unwrap()),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
(mime::APPLICATION, mime::OCTET_STREAM) => {
|
||||
@@ -100,7 +106,10 @@ pub fn fetch(
|
||||
Ok((
|
||||
None,
|
||||
Value::Binary(buf),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
))
|
||||
}
|
||||
@@ -116,14 +125,20 @@ pub fn fetch(
|
||||
Ok((
|
||||
Some(image_ty.to_string()),
|
||||
Value::Binary(buf),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
))
|
||||
}
|
||||
(mime::TEXT, mime::HTML) => Ok((
|
||||
Some("html".to_string()),
|
||||
Value::string(r.text().unwrap()),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
(mime::TEXT, mime::PLAIN) => {
|
||||
@@ -141,7 +156,10 @@ pub fn fetch(
|
||||
Ok((
|
||||
path_extension,
|
||||
Value::string(r.text().unwrap()),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
))
|
||||
}
|
||||
@@ -151,7 +169,10 @@ pub fn fetch(
|
||||
"Not yet supported MIME type: {} {}",
|
||||
ty, sub_ty
|
||||
)),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
}
|
||||
@@ -159,7 +180,10 @@ pub fn fetch(
|
||||
None => Ok((
|
||||
None,
|
||||
Value::string(format!("No content type found")),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::Url(r.url().to_string()),
|
||||
)),
|
||||
},
|
||||
@@ -179,13 +203,19 @@ pub fn fetch(
|
||||
cwd.extension()
|
||||
.map(|name| name.to_string_lossy().to_string()),
|
||||
Value::string(s),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::File(cwd.to_string_lossy().to_string()),
|
||||
)),
|
||||
Err(_) => Ok((
|
||||
None,
|
||||
Value::Binary(bytes),
|
||||
Span::unknown_with_uuid(Uuid::new_v4()),
|
||||
Tag {
|
||||
span,
|
||||
origin: Some(Uuid::new_v4()),
|
||||
},
|
||||
SpanSource::File(cwd.to_string_lossy().to_string()),
|
||||
)),
|
||||
},
|
||||
@@ -203,69 +233,57 @@ pub fn fetch(
|
||||
pub fn parse_as_value(
|
||||
extension: Option<String>,
|
||||
contents: String,
|
||||
contents_span: Span,
|
||||
name_span: Option<Span>,
|
||||
contents_tag: Tag,
|
||||
name_span: Span,
|
||||
) -> 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.tagged(contents_span))
|
||||
.map_err(move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
"Could not open as CSV",
|
||||
"could not open as CSV",
|
||||
name_span,
|
||||
)
|
||||
})
|
||||
}
|
||||
Some(x) if x == "csv" => crate::commands::from_csv::from_csv_string_to_value(
|
||||
contents,
|
||||
contents_tag,
|
||||
)
|
||||
.map_err(move |_| {
|
||||
ShellError::labeled_error("Could not open as CSV", "could not open as CSV", name_span)
|
||||
}),
|
||||
Some(x) if x == "toml" => {
|
||||
crate::commands::from_toml::from_toml_string_to_value(contents, contents_span)
|
||||
.map(|c| c.tagged(contents_span))
|
||||
.map_err(move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
crate::commands::from_toml::from_toml_string_to_value(contents, contents_tag).map_err(
|
||||
move |_| {
|
||||
ShellError::labeled_error(
|
||||
"Could not open as TOML",
|
||||
"could not open as TOML",
|
||||
name_span,
|
||||
)
|
||||
})
|
||||
}
|
||||
Some(x) if x == "json" => {
|
||||
crate::commands::from_json::from_json_string_to_value(contents, contents_span)
|
||||
.map(|c| c.tagged(contents_span))
|
||||
.map_err(move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
"Could not open as JSON",
|
||||
"could not open as JSON",
|
||||
name_span,
|
||||
)
|
||||
})
|
||||
}
|
||||
Some(x) if x == "ini" => {
|
||||
crate::commands::from_ini::from_ini_string_to_value(contents, contents_span)
|
||||
.map(|c| c.tagged(contents_span))
|
||||
.map_err(move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
"Could not open as INI",
|
||||
"could not open as INI",
|
||||
name_span,
|
||||
)
|
||||
})
|
||||
}
|
||||
Some(x) if x == "xml" => {
|
||||
crate::commands::from_xml::from_xml_string_to_value(contents, contents_span).map_err(
|
||||
move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
"Could not open as XML",
|
||||
"could not open as XML",
|
||||
name_span,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
Some(x) if x == "yml" => {
|
||||
crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_span).map_err(
|
||||
Some(x) if x == "json" => {
|
||||
crate::commands::from_json::from_json_string_to_value(contents, contents_tag).map_err(
|
||||
move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
ShellError::labeled_error(
|
||||
"Could not open as JSON",
|
||||
"could not open as JSON",
|
||||
name_span,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
Some(x) if x == "ini" => crate::commands::from_ini::from_ini_string_to_value(
|
||||
contents,
|
||||
contents_tag,
|
||||
)
|
||||
.map_err(move |_| {
|
||||
ShellError::labeled_error("Could not open as INI", "could not open as INI", name_span)
|
||||
}),
|
||||
Some(x) if x == "xml" => crate::commands::from_xml::from_xml_string_to_value(
|
||||
contents,
|
||||
contents_tag,
|
||||
)
|
||||
.map_err(move |_| {
|
||||
ShellError::labeled_error("Could not open as XML", "could not open as XML", name_span)
|
||||
}),
|
||||
Some(x) if x == "yml" => {
|
||||
crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_tag).map_err(
|
||||
move |_| {
|
||||
ShellError::labeled_error(
|
||||
"Could not open as YAML",
|
||||
"could not open as YAML",
|
||||
name_span,
|
||||
@@ -274,9 +292,9 @@ pub fn parse_as_value(
|
||||
)
|
||||
}
|
||||
Some(x) if x == "yaml" => {
|
||||
crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_span).map_err(
|
||||
crate::commands::from_yaml::from_yaml_string_to_value(contents, contents_tag).map_err(
|
||||
move |_| {
|
||||
ShellError::maybe_labeled_error(
|
||||
ShellError::labeled_error(
|
||||
"Could not open as YAML",
|
||||
"could not open as YAML",
|
||||
name_span,
|
||||
@@ -284,6 +302,6 @@ pub fn parse_as_value(
|
||||
},
|
||||
)
|
||||
}
|
||||
_ => Ok(Value::string(contents).tagged(contents_span)),
|
||||
_ => Ok(Value::string(contents).tagged(contents_tag)),
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ use crate::prelude::*;
|
||||
|
||||
pub fn pick(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Pick requires fields",
|
||||
"needs parameter",
|
||||
args.call_info.name_span,
|
||||
@@ -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.tag()));
|
||||
|
||||
Ok(objects.from_input_stream())
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ pub fn ps(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
|
||||
let list = list
|
||||
.into_iter()
|
||||
.map(|(_, process)| process_dict(process, args.call_info.name_span))
|
||||
.map(|(_, process)| process_dict(process, Tag::unknown_origin(args.call_info.name_span)))
|
||||
.collect::<VecDeque<_>>();
|
||||
|
||||
Ok(list.from_input_stream())
|
||||
|
@@ -3,10 +3,8 @@ use crate::object::base::reject_fields;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub fn reject(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let name_span = args.call_info.name_span;
|
||||
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Reject requires fields",
|
||||
"needs parameter",
|
||||
args.call_info.name_span,
|
||||
@@ -16,11 +14,10 @@ pub fn reject(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let fields: Result<Vec<String>, _> = args.positional_iter().map(|a| a.as_string()).collect();
|
||||
let fields = fields?;
|
||||
|
||||
let stream = args.input.values.map(move |item| {
|
||||
reject_fields(&item, &fields, item.span())
|
||||
.into_tagged_value()
|
||||
.tagged(name_span)
|
||||
});
|
||||
let stream = args
|
||||
.input
|
||||
.values
|
||||
.map(move |item| reject_fields(&item, &fields, item.tag()).into_tagged_value());
|
||||
|
||||
Ok(stream.from_input_stream())
|
||||
}
|
||||
|
@@ -61,7 +61,7 @@ pub fn rm(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
return Err(ShellError::labeled_error(
|
||||
"is a directory",
|
||||
"",
|
||||
args.call_info.name_span.unwrap(),
|
||||
args.call_info.name_span,
|
||||
));
|
||||
}
|
||||
std::fs::remove_dir_all(&path).expect("can not remove directory");
|
||||
|
@@ -21,18 +21,14 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
if args.call_info.args.positional.is_none() {
|
||||
// If there is no filename, check the metadata for the origin filename
|
||||
if args.input.len() > 0 {
|
||||
let span = args.input[0].span();
|
||||
match span
|
||||
.source
|
||||
.map(|x| args.call_info.source_map.get(&x))
|
||||
.flatten()
|
||||
{
|
||||
let origin = args.input[0].origin();
|
||||
match origin.map(|x| args.call_info.source_map.get(&x)).flatten() {
|
||||
Some(path) => match path {
|
||||
SpanSource::File(file) => {
|
||||
full_path.push(Path::new(file));
|
||||
}
|
||||
_ => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Save requires a filepath",
|
||||
"needs path",
|
||||
args.call_info.name_span,
|
||||
@@ -40,7 +36,8 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
}
|
||||
},
|
||||
None => {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
println!("Could not find origin");
|
||||
return Err(ShellError::labeled_error(
|
||||
"Save requires a filepath",
|
||||
"needs path",
|
||||
args.call_info.name_span,
|
||||
@@ -48,7 +45,7 @@ pub fn save(args: SinkCommandArgs) -> Result<(), ShellError> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Save requires a filepath",
|
||||
"needs path",
|
||||
args.call_info.name_span,
|
||||
|
@@ -4,20 +4,23 @@ use crate::prelude::*;
|
||||
|
||||
pub fn size(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let input = args.input;
|
||||
let span = args.call_info.name_span;
|
||||
Ok(input
|
||||
.values
|
||||
.map(move |v| match v.item {
|
||||
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()),
|
||||
Value::Primitive(Primitive::String(ref s)) => ReturnSuccess::value(count(s, v.tag())),
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
v.span(),
|
||||
)),
|
||||
})
|
||||
.to_output_stream())
|
||||
}
|
||||
|
||||
fn count(contents: &str, span: impl Into<Span>) -> Tagged<Value> {
|
||||
fn count(contents: &str, tag: impl Into<Tag>) -> Tagged<Value> {
|
||||
let mut lines: i64 = 0;
|
||||
let mut words: i64 = 0;
|
||||
let mut chars: i64 = 0;
|
||||
@@ -42,7 +45,7 @@ fn count(contents: &str, span: impl Into<Span>) -> Tagged<Value> {
|
||||
}
|
||||
}
|
||||
|
||||
let mut dict = TaggedDictBuilder::new(span);
|
||||
let mut dict = TaggedDictBuilder::new(tag);
|
||||
//TODO: add back in name when we have it in the span
|
||||
//dict.insert("name", Value::string(name));
|
||||
dict.insert("lines", Value::int(lines));
|
||||
|
@@ -27,7 +27,7 @@ impl Command for SkipWhile {
|
||||
|
||||
pub fn skip_while(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
if args.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Where requires a condition",
|
||||
"needs condition",
|
||||
args.call_info.name_span,
|
||||
|
@@ -8,7 +8,7 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
if positional.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Split-column needs more information",
|
||||
"needs parameter (eg split-column \",\")",
|
||||
args.call_info.name_span,
|
||||
@@ -34,14 +34,14 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
gen_columns.push(format!("Column{}", i + 1));
|
||||
}
|
||||
|
||||
let mut dict = TaggedDictBuilder::new(v.span());
|
||||
let mut dict = TaggedDictBuilder::new(v.tag());
|
||||
for (&k, v) in split_result.iter().zip(gen_columns.iter()) {
|
||||
dict.insert(v.clone(), Primitive::String(k.into()));
|
||||
}
|
||||
|
||||
ReturnSuccess::value(dict.into_tagged_value())
|
||||
} else if split_result.len() == (positional.len() - 1) {
|
||||
let mut dict = TaggedDictBuilder::new(v.span());
|
||||
let mut dict = TaggedDictBuilder::new(v.tag());
|
||||
for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) {
|
||||
dict.insert(
|
||||
v.as_string().unwrap(),
|
||||
@@ -50,17 +50,19 @@ pub fn split_column(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
}
|
||||
ReturnSuccess::value(dict.into_tagged_value())
|
||||
} else {
|
||||
let mut dict = TaggedDictBuilder::new(v.span());
|
||||
let mut dict = TaggedDictBuilder::new(v.tag());
|
||||
for k in positional.iter().skip(1) {
|
||||
dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into()));
|
||||
}
|
||||
ReturnSuccess::value(dict.into_tagged_value())
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
_ => Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
v.span(),
|
||||
)),
|
||||
})
|
||||
.to_output_stream())
|
||||
|
@@ -8,7 +8,7 @@ pub fn split_row(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
let span = args.call_info.name_span;
|
||||
|
||||
if positional.len() == 0 {
|
||||
return Err(ShellError::maybe_labeled_error(
|
||||
return Err(ShellError::labeled_error(
|
||||
"Split-row needs more information",
|
||||
"needs parameter (eg split-row \"\\n\")",
|
||||
args.call_info.name_span,
|
||||
@@ -30,17 +30,19 @@ 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())).tagged(v.span()),
|
||||
Value::Primitive(Primitive::String(s.into())).simple_spanned(v.span()),
|
||||
));
|
||||
}
|
||||
result
|
||||
}
|
||||
_ => {
|
||||
let mut result = VecDeque::new();
|
||||
result.push_back(Err(ShellError::maybe_labeled_error(
|
||||
"Expected string values from pipeline",
|
||||
"expects strings from pipeline",
|
||||
result.push_back(Err(ShellError::labeled_error_with_secondary(
|
||||
"Expected a string from pipeline",
|
||||
"requires string input",
|
||||
span,
|
||||
"value originates from here",
|
||||
v.span(),
|
||||
)));
|
||||
result
|
||||
}
|
||||
|
@@ -8,18 +8,19 @@ pub fn tags(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
.input
|
||||
.values
|
||||
.map(move |v| {
|
||||
let mut tags = TaggedDictBuilder::new(v.span());
|
||||
let mut tags = TaggedDictBuilder::new(v.tag());
|
||||
{
|
||||
let origin = v.origin();
|
||||
let span = v.span();
|
||||
let mut dict = TaggedDictBuilder::new(v.span());
|
||||
let mut dict = TaggedDictBuilder::new(v.tag());
|
||||
dict.insert("start", Value::int(span.start as i64));
|
||||
dict.insert("end", Value::int(span.end as i64));
|
||||
match span.source.map(|x| source_map.get(&x)).flatten() {
|
||||
match origin.map(|x| source_map.get(&x)).flatten() {
|
||||
Some(SpanSource::File(source)) => {
|
||||
dict.insert("source", Value::string(source));
|
||||
dict.insert("origin", Value::string(source));
|
||||
}
|
||||
Some(SpanSource::Url(source)) => {
|
||||
dict.insert("source", Value::string(source));
|
||||
dict.insert("origin", Value::string(source));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@@ -42,8 +42,10 @@ pub fn to_csv(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
Ok(out
|
||||
.values
|
||||
.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(
|
||||
Ok(x) => ReturnSuccess::value(
|
||||
Value::Primitive(Primitive::String(x)).simple_spanned(name_span),
|
||||
),
|
||||
Err(_) => Err(ShellError::labeled_error(
|
||||
"Can not convert to CSV string",
|
||||
"can not convert piped data to CSV string",
|
||||
name_span,
|
||||
|
@@ -48,10 +48,10 @@ pub fn to_json(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
.values
|
||||
.map(
|
||||
move |a| match serde_json::to_string(&value_to_json_value(&a)) {
|
||||
Ok(x) => {
|
||||
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span))
|
||||
}
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Ok(x) => ReturnSuccess::value(
|
||||
Value::Primitive(Primitive::String(x)).simple_spanned(name_span),
|
||||
),
|
||||
Err(_) => Err(ShellError::labeled_error(
|
||||
"Can not convert to JSON string",
|
||||
"can not convert piped data to JSON string",
|
||||
name_span,
|
||||
|
@@ -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)).tagged(name_span),
|
||||
Value::Primitive(Primitive::String(val)).simple_spanned(name_span),
|
||||
)
|
||||
}
|
||||
|
||||
Err(err) => Err(ShellError::type_error(
|
||||
"Can not convert to a TOML string",
|
||||
format!("{:?} - {:?}", a.type_name(), err).tagged(name_span),
|
||||
format!("{:?} - {:?}", a.type_name(), err).simple_spanned(name_span),
|
||||
)),
|
||||
})
|
||||
.to_output_stream())
|
||||
|
@@ -46,10 +46,10 @@ pub fn to_yaml(args: CommandArgs) -> Result<OutputStream, ShellError> {
|
||||
.values
|
||||
.map(
|
||||
move |a| match serde_yaml::to_string(&value_to_yaml_value(&a)) {
|
||||
Ok(x) => {
|
||||
ReturnSuccess::value(Value::Primitive(Primitive::String(x)).tagged(name_span))
|
||||
}
|
||||
Err(_) => Err(ShellError::maybe_labeled_error(
|
||||
Ok(x) => ReturnSuccess::value(
|
||||
Value::Primitive(Primitive::String(x)).simple_spanned(name_span),
|
||||
),
|
||||
Err(_) => Err(ShellError::labeled_error(
|
||||
"Can not convert to YAML string",
|
||||
"can not convert piped data to YAML string",
|
||||
name_span,
|
||||
|
@@ -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()).tagged(v.span()))
|
||||
ReturnSuccess::value(Value::string(string.trim()).simple_spanned(v.span()))
|
||||
})
|
||||
.to_output_stream())
|
||||
}
|
||||
|
Reference in New Issue
Block a user