allow Range to expand to array-like when converting to json (#8047)

# Description
Fixes #8002, which expands ranges `1..3` to expand to array-like when
saving and converting to json. Now,

```
> 1..3 | save foo.json
# foo.json
[
    1,
    2,
    3
]


> 1..3 | to json
[
    1,
    2,
    3
]
```
# 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:

- [X] `cargo fmt --all -- --check` to check standard code formatting
(`cargo fmt --all` applies these changes)
- [X] `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A
clippy::needless_collect` to check that you're using the standard code
style
- [X] `cargo test --workspace` to check that all tests pass

# 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.
This commit is contained in:
David Matos
2023-02-24 22:31:33 +01:00
committed by GitHub
parent 253b223e65
commit 42f0b55de0
8 changed files with 94 additions and 0 deletions

View File

@ -604,6 +604,53 @@ impl PipelineData {
(self, false)
}
}
/// Try to convert Value from Value::Range to Value::List.
/// This is useful to expand Value::Range into array notation, specifically when
/// converting `to json` or `to nuon`.
/// `1..3 | to XX -> [1,2,3]`
pub fn try_expand_range(self) -> Result<PipelineData, ShellError> {
let input = match self {
PipelineData::Value(Value::Range { val, span }, ..) => {
match (&val.to, &val.from) {
(Value::Float { val, .. }, _) | (_, Value::Float { val, .. }) => {
if *val == f64::INFINITY || *val == f64::NEG_INFINITY {
return Err(ShellError::GenericError(
"Cannot create range".into(),
"Infinity is not allowed when converting to json".into(),
Some(span),
Some("Consider removing infinity".into()),
vec![],
));
}
}
(Value::Int { val, span }, _) => {
if *val == i64::MAX || *val == i64::MIN {
return Err(ShellError::GenericError(
"Cannot create range".into(),
"Unbounded ranges are not allowed when converting to json".into(),
Some(*span),
Some(
"Consider using ranges with valid start and end point.".into(),
),
vec![],
));
}
}
_ => (),
}
let range_values: Vec<Value> = val.into_range_iter(None)?.collect();
PipelineData::Value(
Value::List {
vals: range_values,
span,
},
None,
)
}
_ => self,
};
Ok(input)
}
/// Consume and print self data immediately.
///