mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 02:35:00 +02:00
Move Value to helpers, separate span call (#10121)
# Description As part of the refactor to split spans off of Value, this moves to using helper functions to create values, and using `.span()` instead of matching span out of Value directly. Hoping to get a few more helping hands to finish this, as there are a lot of commands to update :) # User-Facing Changes <!-- List of all changes that impact the user experience here. This helps us keep track of breaking changes. --> # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass (on Windows make sure to [enable developer mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging)) - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --> --------- Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com> Co-authored-by: WindSoilder <windsoilder@outlook.com>
This commit is contained in:
@ -32,16 +32,16 @@ impl Command for From {
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
Ok(Value::String {
|
||||
val: get_full_help(
|
||||
Ok(Value::string(
|
||||
get_full_help(
|
||||
&From.signature(),
|
||||
&From.examples(),
|
||||
engine_state,
|
||||
stack,
|
||||
self.is_parser_keyword(),
|
||||
),
|
||||
span: call.head,
|
||||
}
|
||||
call.head,
|
||||
)
|
||||
.into_pipeline_data())
|
||||
}
|
||||
}
|
||||
|
@ -81,16 +81,16 @@ impl Command for FromCsv {
|
||||
Example {
|
||||
description: "Convert comma-separated data to a table",
|
||||
example: "\"ColA,ColB\n1,2\" | from csv",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list (
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["ColA".to_string(), "ColB".to_string()],
|
||||
vals: vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
})
|
||||
Span::test_data(),
|
||||
))
|
||||
},
|
||||
Example {
|
||||
description: "Convert comma-separated data to a table, ignoring headers",
|
||||
|
@ -38,22 +38,16 @@ fn from_delimited_string_to_value(
|
||||
let mut output_row = vec![];
|
||||
for value in row?.iter() {
|
||||
if no_infer {
|
||||
output_row.push(Value::String {
|
||||
span,
|
||||
val: value.into(),
|
||||
});
|
||||
output_row.push(Value::string(value.to_string(), span));
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Ok(i) = value.parse::<i64>() {
|
||||
output_row.push(Value::Int { val: i, span });
|
||||
output_row.push(Value::int(i, span));
|
||||
} else if let Ok(f) = value.parse::<f64>() {
|
||||
output_row.push(Value::Float { val: f, span });
|
||||
output_row.push(Value::float(f, span));
|
||||
} else {
|
||||
output_row.push(Value::String {
|
||||
val: value.into(),
|
||||
span,
|
||||
});
|
||||
output_row.push(Value::string(value.to_string(), span));
|
||||
}
|
||||
}
|
||||
rows.push(Value::record(
|
||||
@ -65,7 +59,7 @@ fn from_delimited_string_to_value(
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Value::List { vals: rows, span })
|
||||
Ok(Value::list(rows, span))
|
||||
}
|
||||
|
||||
pub(super) struct DelimitedReaderConfig {
|
||||
@ -96,7 +90,11 @@ pub(super) fn from_delimited_data(
|
||||
|
||||
pub fn trim_from_str(trim: Option<Value>) -> Result<Trim, ShellError> {
|
||||
match trim {
|
||||
Some(Value::String { val: item, span }) => match item.as_str() {
|
||||
Some(v) => {
|
||||
let span = v.span();
|
||||
match v {
|
||||
Value::String {val: item, ..} => match item.as_str() {
|
||||
|
||||
"all" => Ok(Trim::All),
|
||||
"headers" => Ok(Trim::Headers),
|
||||
"fields" => Ok(Trim::Fields),
|
||||
@ -107,7 +105,10 @@ pub fn trim_from_str(trim: Option<Value>) -> Result<Trim, ShellError> {
|
||||
.into(),
|
||||
span,
|
||||
}),
|
||||
},
|
||||
}
|
||||
_ => Ok(Trim::None),
|
||||
}
|
||||
}
|
||||
_ => Ok(Trim::None),
|
||||
}
|
||||
}
|
||||
|
@ -41,10 +41,10 @@ impl Command for FromJson {
|
||||
cols: vec!["a".to_string(), "b".to_string()],
|
||||
vals: vec![
|
||||
Value::test_int(1),
|
||||
Value::List {
|
||||
vals: vec![Value::test_int(1), Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::list(
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
Span::test_data(),
|
||||
),
|
||||
],
|
||||
})),
|
||||
},
|
||||
@ -75,10 +75,7 @@ impl Command for FromJson {
|
||||
} else {
|
||||
match convert_string_to_value(x.to_string(), span) {
|
||||
Ok(v) => Some(v),
|
||||
Err(error) => Some(Value::Error {
|
||||
error: Box::new(error),
|
||||
span,
|
||||
}),
|
||||
Err(error) => Some(Value::error(error, span)),
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -100,12 +97,12 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value {
|
||||
.map(|x| convert_nujson_to_value(x, span))
|
||||
.collect();
|
||||
|
||||
Value::List { vals: v, span }
|
||||
Value::list(v, span)
|
||||
}
|
||||
nu_json::Value::Bool(b) => Value::Bool { val: *b, span },
|
||||
nu_json::Value::F64(f) => Value::Float { val: *f, span },
|
||||
nu_json::Value::I64(i) => Value::Int { val: *i, span },
|
||||
nu_json::Value::Null => Value::Nothing { span },
|
||||
nu_json::Value::Bool(b) => Value::bool(*b, span),
|
||||
nu_json::Value::F64(f) => Value::float(*f, span),
|
||||
nu_json::Value::I64(i) => Value::int(*i, span),
|
||||
nu_json::Value::Null => Value::nothing(span),
|
||||
nu_json::Value::Object(k) => Value::record(
|
||||
k.iter()
|
||||
.map(|(k, v)| (k.clone(), convert_nujson_to_value(v, span)))
|
||||
@ -114,26 +111,20 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value {
|
||||
),
|
||||
nu_json::Value::U64(u) => {
|
||||
if *u > i64::MAX as u64 {
|
||||
Value::Error {
|
||||
error: Box::new(ShellError::CantConvert {
|
||||
Value::error(
|
||||
ShellError::CantConvert {
|
||||
to_type: "i64 sized integer".into(),
|
||||
from_type: "value larger than i64".into(),
|
||||
span,
|
||||
help: None,
|
||||
}),
|
||||
},
|
||||
span,
|
||||
}
|
||||
)
|
||||
} else {
|
||||
Value::Int {
|
||||
val: *u as i64,
|
||||
span,
|
||||
}
|
||||
Value::int(*u as i64, span)
|
||||
}
|
||||
}
|
||||
nu_json::Value::String(s) => Value::String {
|
||||
val: s.clone(),
|
||||
span,
|
||||
},
|
||||
nu_json::Value::String(s) => Value::string(s.clone(), span),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,10 +39,10 @@ impl Command for FromNuon {
|
||||
cols: vec!["a".to_string(), "b".to_string()],
|
||||
vals: vec![
|
||||
Value::test_int(1),
|
||||
Value::List {
|
||||
vals: vec![Value::test_int(1), Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::list(
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
Span::test_data(),
|
||||
),
|
||||
],
|
||||
})),
|
||||
},
|
||||
@ -206,8 +206,8 @@ fn convert_to_value(
|
||||
"closures not supported in nuon".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::Binary(val) => Ok(Value::Binary { val, span }),
|
||||
Expr::Bool(val) => Ok(Value::Bool { val, span }),
|
||||
Expr::Binary(val) => Ok(Value::binary(val, span)),
|
||||
Expr::Bool(val) => Ok(Value::bool(val, span)),
|
||||
Expr::Call(..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"Error when loading".into(),
|
||||
@ -220,16 +220,16 @@ fn convert_to_value(
|
||||
"subexpressions and cellpaths not supported in nuon".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::DateTime(dt) => Ok(Value::Date { val: dt, span }),
|
||||
Expr::DateTime(dt) => Ok(Value::date(dt, span)),
|
||||
Expr::ExternalCall(..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"Error when loading".into(),
|
||||
"calls not supported in nuon".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::Filepath(val) => Ok(Value::String { val, span }),
|
||||
Expr::Directory(val) => Ok(Value::String { val, span }),
|
||||
Expr::Float(val) => Ok(Value::Float { val, span }),
|
||||
Expr::Filepath(val) => Ok(Value::string(val, span)),
|
||||
Expr::Directory(val) => Ok(Value::string(val, span)),
|
||||
Expr::Float(val) => Ok(Value::float(val, span)),
|
||||
Expr::FullCellPath(full_cell_path) => {
|
||||
if !full_cell_path.tail.is_empty() {
|
||||
Err(ShellError::OutsideSpannedLabeledError(
|
||||
@ -255,7 +255,7 @@ fn convert_to_value(
|
||||
"extra tokens in input file".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::GlobPattern(val) => Ok(Value::String { val, span }),
|
||||
Expr::GlobPattern(val) => Ok(Value::string(val, span)),
|
||||
Expr::ImportPattern(..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"Error when loading".into(),
|
||||
@ -268,7 +268,7 @@ fn convert_to_value(
|
||||
"overlays not supported in nuon".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::Int(val) => Ok(Value::Int { val, span }),
|
||||
Expr::Int(val) => Ok(Value::int(val, span)),
|
||||
Expr::Keyword(kw, ..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"Error when loading".into(),
|
||||
@ -281,7 +281,7 @@ fn convert_to_value(
|
||||
output.push(convert_to_value(val, span, original_text)?);
|
||||
}
|
||||
|
||||
Ok(Value::List { vals: output, span })
|
||||
Ok(Value::list(output, span))
|
||||
}
|
||||
Expr::MatchBlock(..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
@ -289,7 +289,7 @@ fn convert_to_value(
|
||||
"match blocks not supported in nuon".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::Nothing => Ok(Value::Nothing { span }),
|
||||
Expr::Nothing => Ok(Value::nothing(span)),
|
||||
Expr::Operator(..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"Error when loading".into(),
|
||||
@ -300,25 +300,25 @@ fn convert_to_value(
|
||||
let from = if let Some(f) = from {
|
||||
convert_to_value(*f, span, original_text)?
|
||||
} else {
|
||||
Value::Nothing { span: expr.span }
|
||||
Value::nothing(expr.span)
|
||||
};
|
||||
|
||||
let next = if let Some(s) = next {
|
||||
convert_to_value(*s, span, original_text)?
|
||||
} else {
|
||||
Value::Nothing { span: expr.span }
|
||||
Value::nothing(expr.span)
|
||||
};
|
||||
|
||||
let to = if let Some(t) = to {
|
||||
convert_to_value(*t, span, original_text)?
|
||||
} else {
|
||||
Value::Nothing { span: expr.span }
|
||||
Value::nothing(expr.span)
|
||||
};
|
||||
|
||||
Ok(Value::Range {
|
||||
val: Box::new(Range::new(expr.span, from, next, to, &operator)?),
|
||||
span: expr.span,
|
||||
})
|
||||
Ok(Value::range(
|
||||
Range::new(expr.span, from, next, to, &operator)?,
|
||||
expr.span,
|
||||
))
|
||||
}
|
||||
Expr::Record(key_vals) => {
|
||||
let mut record = Record::new();
|
||||
@ -355,7 +355,7 @@ fn convert_to_value(
|
||||
"signatures not supported in nuon".into(),
|
||||
expr.span,
|
||||
)),
|
||||
Expr::String(s) => Ok(Value::String { val: s, span }),
|
||||
Expr::String(s) => Ok(Value::string(s, span)),
|
||||
Expr::StringInterpolation(..) => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"Error when loading".into(),
|
||||
@ -414,7 +414,7 @@ fn convert_to_value(
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Value::List { vals: output, span })
|
||||
Ok(Value::list(output, span))
|
||||
}
|
||||
Expr::ValueWithUnit(val, unit) => {
|
||||
let size = match val.expr {
|
||||
@ -430,80 +430,41 @@ fn convert_to_value(
|
||||
};
|
||||
|
||||
match unit.item {
|
||||
Unit::Byte => Ok(Value::Filesize { val: size, span }),
|
||||
Unit::Kilobyte => Ok(Value::Filesize {
|
||||
val: size * 1000,
|
||||
Unit::Byte => Ok(Value::filesize(size, span)),
|
||||
Unit::Kilobyte => Ok(Value::filesize(size * 1000, span)),
|
||||
Unit::Megabyte => Ok(Value::filesize(size * 1000 * 1000, span)),
|
||||
Unit::Gigabyte => Ok(Value::filesize(size * 1000 * 1000 * 1000, span)),
|
||||
Unit::Terabyte => Ok(Value::filesize(size * 1000 * 1000 * 1000 * 1000, span)),
|
||||
Unit::Petabyte => Ok(Value::filesize(
|
||||
size * 1000 * 1000 * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Megabyte => Ok(Value::Filesize {
|
||||
val: size * 1000 * 1000,
|
||||
)),
|
||||
Unit::Exabyte => Ok(Value::filesize(
|
||||
size * 1000 * 1000 * 1000 * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Gigabyte => Ok(Value::Filesize {
|
||||
val: size * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Terabyte => Ok(Value::Filesize {
|
||||
val: size * 1000 * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Petabyte => Ok(Value::Filesize {
|
||||
val: size * 1000 * 1000 * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Exabyte => Ok(Value::Filesize {
|
||||
val: size * 1000 * 1000 * 1000 * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
)),
|
||||
|
||||
Unit::Kibibyte => Ok(Value::Filesize {
|
||||
val: size * 1024,
|
||||
Unit::Kibibyte => Ok(Value::filesize(size * 1024, span)),
|
||||
Unit::Mebibyte => Ok(Value::filesize(size * 1024 * 1024, span)),
|
||||
Unit::Gibibyte => Ok(Value::filesize(size * 1024 * 1024 * 1024, span)),
|
||||
Unit::Tebibyte => Ok(Value::filesize(size * 1024 * 1024 * 1024 * 1024, span)),
|
||||
Unit::Pebibyte => Ok(Value::filesize(
|
||||
size * 1024 * 1024 * 1024 * 1024 * 1024,
|
||||
span,
|
||||
}),
|
||||
Unit::Mebibyte => Ok(Value::Filesize {
|
||||
val: size * 1024 * 1024,
|
||||
)),
|
||||
Unit::Exbibyte => Ok(Value::filesize(
|
||||
size * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
|
||||
span,
|
||||
}),
|
||||
Unit::Gibibyte => Ok(Value::Filesize {
|
||||
val: size * 1024 * 1024 * 1024,
|
||||
span,
|
||||
}),
|
||||
Unit::Tebibyte => Ok(Value::Filesize {
|
||||
val: size * 1024 * 1024 * 1024 * 1024,
|
||||
span,
|
||||
}),
|
||||
Unit::Pebibyte => Ok(Value::Filesize {
|
||||
val: size * 1024 * 1024 * 1024 * 1024 * 1024,
|
||||
span,
|
||||
}),
|
||||
Unit::Exbibyte => Ok(Value::Filesize {
|
||||
val: size * 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
|
||||
span,
|
||||
}),
|
||||
)),
|
||||
|
||||
Unit::Nanosecond => Ok(Value::Duration { val: size, span }),
|
||||
Unit::Microsecond => Ok(Value::Duration {
|
||||
val: size * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Millisecond => Ok(Value::Duration {
|
||||
val: size * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Second => Ok(Value::Duration {
|
||||
val: size * 1000 * 1000 * 1000,
|
||||
span,
|
||||
}),
|
||||
Unit::Minute => Ok(Value::Duration {
|
||||
val: size * 1000 * 1000 * 1000 * 60,
|
||||
span,
|
||||
}),
|
||||
Unit::Hour => Ok(Value::Duration {
|
||||
val: size * 1000 * 1000 * 1000 * 60 * 60,
|
||||
span,
|
||||
}),
|
||||
Unit::Nanosecond => Ok(Value::duration(size, span)),
|
||||
Unit::Microsecond => Ok(Value::duration(size * 1000, span)),
|
||||
Unit::Millisecond => Ok(Value::duration(size * 1000 * 1000, span)),
|
||||
Unit::Second => Ok(Value::duration(size * 1000 * 1000 * 1000, span)),
|
||||
Unit::Minute => Ok(Value::duration(size * 1000 * 1000 * 1000 * 60, span)),
|
||||
Unit::Hour => Ok(Value::duration(size * 1000 * 1000 * 1000 * 60 * 60, span)),
|
||||
Unit::Day => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24) {
|
||||
Some(val) => Ok(Value::Duration { val, span }),
|
||||
Some(val) => Ok(Value::duration(val, span)),
|
||||
None => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"day duration too large".into(),
|
||||
@ -513,7 +474,7 @@ fn convert_to_value(
|
||||
},
|
||||
|
||||
Unit::Week => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24 * 7) {
|
||||
Some(val) => Ok(Value::Duration { val, span }),
|
||||
Some(val) => Ok(Value::duration(val, span)),
|
||||
None => Err(ShellError::OutsideSpannedLabeledError(
|
||||
original_text.to_string(),
|
||||
"week duration too large".into(),
|
||||
|
@ -158,13 +158,7 @@ fn from_ods(
|
||||
sheet_output.push(Value::record(record, head));
|
||||
}
|
||||
|
||||
dict.insert(
|
||||
sheet_name,
|
||||
Value::List {
|
||||
vals: sheet_output,
|
||||
span: head,
|
||||
},
|
||||
);
|
||||
dict.insert(sheet_name, Value::list(sheet_output, head));
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedInput(
|
||||
"Could not load sheet".to_string(),
|
||||
|
@ -44,20 +44,20 @@ impl Command for FromSsv {
|
||||
example: r#"'FOO BAR
|
||||
1 2' | from ssv"#,
|
||||
description: "Converts ssv formatted string to table",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list(
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["FOO".to_string(), "BAR".to_string()],
|
||||
vals: vec![Value::test_string("1"), Value::test_string("2")],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
}, Example {
|
||||
example: r#"'FOO BAR
|
||||
1 2' | from ssv -n"#,
|
||||
description: "Converts ssv formatted string to table but not treating the first row as column names",
|
||||
result: Some(
|
||||
Value::List {
|
||||
vals: vec![
|
||||
Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["column1".to_string(), "column2".to_string()],
|
||||
vals: vec![Value::test_string("FOO"), Value::test_string("BAR")],
|
||||
@ -67,8 +67,8 @@ impl Command for FromSsv {
|
||||
vals: vec![Value::test_string("1"), Value::test_string("2")],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}
|
||||
Span::test_data(),
|
||||
)
|
||||
),
|
||||
}]
|
||||
}
|
||||
@ -280,7 +280,7 @@ fn from_ssv_string_to_value(
|
||||
})
|
||||
.collect();
|
||||
|
||||
Value::List { vals: rows, span }
|
||||
Value::list(rows, span)
|
||||
}
|
||||
|
||||
fn from_ssv(
|
||||
|
@ -41,10 +41,10 @@ b = [1, 2]' | from toml",
|
||||
cols: vec!["a".to_string(), "b".to_string()],
|
||||
vals: vec![
|
||||
Value::test_int(1),
|
||||
Value::List {
|
||||
vals: vec![Value::test_int(1), Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::list(
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
Span::test_data(),
|
||||
),
|
||||
],
|
||||
})),
|
||||
},
|
||||
@ -73,25 +73,19 @@ fn convert_toml_to_value(value: &toml::Value, span: Span) -> Value {
|
||||
.map(|x| convert_toml_to_value(x, span))
|
||||
.collect();
|
||||
|
||||
Value::List { vals: v, span }
|
||||
Value::list(v, span)
|
||||
}
|
||||
toml::Value::Boolean(b) => Value::Bool { val: *b, span },
|
||||
toml::Value::Float(f) => Value::Float { val: *f, span },
|
||||
toml::Value::Integer(i) => Value::Int { val: *i, span },
|
||||
toml::Value::Boolean(b) => Value::bool(*b, span),
|
||||
toml::Value::Float(f) => Value::float(*f, span),
|
||||
toml::Value::Integer(i) => Value::int(*i, span),
|
||||
toml::Value::Table(k) => Value::record(
|
||||
k.iter()
|
||||
.map(|(k, v)| (k.clone(), convert_toml_to_value(v, span)))
|
||||
.collect(),
|
||||
span,
|
||||
),
|
||||
toml::Value::String(s) => Value::String {
|
||||
val: s.clone(),
|
||||
span,
|
||||
},
|
||||
toml::Value::Datetime(d) => Value::String {
|
||||
val: d.to_string(),
|
||||
span,
|
||||
},
|
||||
toml::Value::String(s) => Value::string(s.clone(), span),
|
||||
toml::Value::Datetime(d) => Value::string(d.to_string(), span),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,16 +75,16 @@ impl Command for FromTsv {
|
||||
Example {
|
||||
description: "Convert tab-separated data to a table",
|
||||
example: "\"ColA\tColB\n1\t2\" | from tsv",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::test_record(Record {
|
||||
result: Some(Value::list (
|
||||
vec![Value::test_record(Record {
|
||||
cols: vec!["ColA".to_string(), "ColB".to_string()],
|
||||
vals: vec![
|
||||
Value::test_int(1),
|
||||
Value::test_int(2),
|
||||
],
|
||||
})],
|
||||
span: Span::test_data(),
|
||||
})
|
||||
Span::test_data(),
|
||||
))
|
||||
},
|
||||
Example {
|
||||
description: "Create a tsv file with header columns and open it",
|
||||
|
@ -157,13 +157,7 @@ fn from_xlsx(
|
||||
sheet_output.push(Value::record(record, head));
|
||||
}
|
||||
|
||||
dict.insert(
|
||||
sheet_name,
|
||||
Value::List {
|
||||
vals: sheet_output,
|
||||
span: head,
|
||||
},
|
||||
);
|
||||
dict.insert(sheet_name, Value::list(sheet_output, head));
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedInput(
|
||||
"Could not load sheet".to_string(),
|
||||
|
@ -336,10 +336,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn table(list: &[Value]) -> Value {
|
||||
Value::List {
|
||||
vals: list.to_vec(),
|
||||
span: Span::test_data(),
|
||||
}
|
||||
Value::list(list.to_vec(), Span::test_data())
|
||||
}
|
||||
|
||||
fn content_tag(
|
||||
|
@ -88,28 +88,20 @@ fn convert_yaml_value_to_nu_value(
|
||||
val_span,
|
||||
);
|
||||
Ok(match v {
|
||||
serde_yaml::Value::Bool(b) => Value::Bool { val: *b, span },
|
||||
serde_yaml::Value::Number(n) if n.is_i64() => Value::Int {
|
||||
val: n.as_i64().ok_or(err_not_compatible_number)?,
|
||||
span,
|
||||
},
|
||||
serde_yaml::Value::Number(n) if n.is_f64() => Value::Float {
|
||||
val: n.as_f64().ok_or(err_not_compatible_number)?,
|
||||
span,
|
||||
},
|
||||
serde_yaml::Value::String(s) => Value::String {
|
||||
val: s.to_string(),
|
||||
span,
|
||||
},
|
||||
serde_yaml::Value::Bool(b) => Value::bool(*b, span),
|
||||
serde_yaml::Value::Number(n) if n.is_i64() => {
|
||||
Value::int(n.as_i64().ok_or(err_not_compatible_number)?, span)
|
||||
}
|
||||
serde_yaml::Value::Number(n) if n.is_f64() => {
|
||||
Value::float(n.as_f64().ok_or(err_not_compatible_number)?, span)
|
||||
}
|
||||
serde_yaml::Value::String(s) => Value::string(s.to_string(), span),
|
||||
serde_yaml::Value::Sequence(a) => {
|
||||
let result: Result<Vec<Value>, ShellError> = a
|
||||
.iter()
|
||||
.map(|x| convert_yaml_value_to_nu_value(x, span, val_span))
|
||||
.collect();
|
||||
Value::List {
|
||||
vals: result?,
|
||||
span,
|
||||
}
|
||||
Value::list(result?, span)
|
||||
}
|
||||
serde_yaml::Value::Mapping(t) => {
|
||||
// Using an IndexMap ensures consistent ordering
|
||||
@ -155,10 +147,7 @@ fn convert_yaml_value_to_nu_value(
|
||||
.first()
|
||||
.and_then(|e| match e {
|
||||
(serde_yaml::Value::String(s), serde_yaml::Value::Null) => {
|
||||
Some(Value::String {
|
||||
val: "{{ ".to_owned() + s.as_str() + " }}",
|
||||
span,
|
||||
})
|
||||
Some(Value::string("{{ ".to_owned() + s.as_str() + " }}", span))
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
@ -177,19 +166,19 @@ fn convert_yaml_value_to_nu_value(
|
||||
let value = match &t.value {
|
||||
serde_yaml::Value::String(s) => {
|
||||
let val = format!("{} {}", tag, s).trim().to_string();
|
||||
Value::String { val, span }
|
||||
Value::string(val, span)
|
||||
}
|
||||
serde_yaml::Value::Number(n) => {
|
||||
let val = format!("{} {}", tag, n).trim().to_string();
|
||||
Value::String { val, span }
|
||||
Value::string(val, span)
|
||||
}
|
||||
serde_yaml::Value::Bool(b) => {
|
||||
let val = format!("{} {}", tag, b).trim().to_string();
|
||||
Value::String { val, span }
|
||||
Value::string(val, span)
|
||||
}
|
||||
serde_yaml::Value::Null => {
|
||||
let val = format!("{}", tag).trim().to_string();
|
||||
Value::String { val, span }
|
||||
Value::string(val, span)
|
||||
}
|
||||
v => convert_yaml_value_to_nu_value(v, span, val_span)?,
|
||||
};
|
||||
@ -223,10 +212,7 @@ pub fn from_yaml_string_to_value(
|
||||
match documents.len() {
|
||||
0 => Ok(Value::nothing(span)),
|
||||
1 => Ok(documents.remove(0)),
|
||||
_ => Ok(Value::List {
|
||||
vals: documents,
|
||||
span,
|
||||
}),
|
||||
_ => Ok(Value::list(documents, span)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,22 +229,22 @@ pub fn get_examples() -> Vec<Example<'static>> {
|
||||
Example {
|
||||
example: "'[ a: 1, b: [1, 2] ]' | from yaml",
|
||||
description: "Converts yaml formatted string to table",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["a".to_string()],
|
||||
vals: vec![Value::test_int(1)],
|
||||
}),
|
||||
Value::test_record(Record {
|
||||
cols: vec!["b".to_string()],
|
||||
vals: vec![Value::List {
|
||||
vals: vec![Value::test_int(1), Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
}],
|
||||
vals: vec![Value::list(
|
||||
vec![Value::test_int(1), Value::test_int(2)],
|
||||
Span::test_data(),
|
||||
)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -349,8 +335,8 @@ mod test {
|
||||
Span::test_data(),
|
||||
);
|
||||
|
||||
let expected: Result<Value, ShellError> = Ok(Value::List {
|
||||
vals: vec![
|
||||
let expected: Result<Value, ShellError> = Ok(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["a".to_string(), "b".to_string()],
|
||||
vals: vec![Value::test_string("b"), Value::test_string("c")],
|
||||
@ -360,8 +346,8 @@ mod test {
|
||||
vals: vec![Value::test_string("g"), Value::test_string("h")],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
});
|
||||
Span::test_data(),
|
||||
));
|
||||
|
||||
// Unfortunately the eq function for Value doesn't compare well enough to detect
|
||||
// ordering errors in List columns or values.
|
||||
|
Reference in New Issue
Block a user