fix nuon conversions of range values (#14687)

# Description
Currently the step size of range values are discarded when converting to
nuon. This PR fixes that and makes `to nuon | from nuon` round trips
work.

# User-Facing Changes
`to nuon` conversion of `range` values now include the step size

# Tests + Formatting
Added some additional tests to cover inclusive/exclusive integer/float
and step size cases.
This commit is contained in:
Bahex
2025-01-07 23:29:39 +03:00
committed by GitHub
parent 8e41a308cd
commit 16e174be7e
5 changed files with 82 additions and 73 deletions

View File

@ -1,10 +1,9 @@
use core::fmt::Write;
use nu_engine::get_columns;
use nu_protocol::format::ObviousFloat;
use nu_protocol::{engine::EngineState, Range, ShellError, Span, Value};
use nu_utils::{escape_quote_string, needs_quoting};
use std::ops::Bound;
/// control the way Nushell [`Value`] is converted to NUON data
pub enum ToStyle {
/// no indentation at all
@ -138,14 +137,7 @@ fn value_to_string(
Value::Error { error, .. } => Err(*error.clone()),
// FIXME: make filesizes use the shortest lossless representation.
Value::Filesize { val, .. } => Ok(format!("{}b", val.get())),
Value::Float { val, .. } => {
// This serialises these as 'nan', 'inf' and '-inf', respectively.
if &val.round() == val && val.is_finite() {
Ok(format!("{}.0", *val))
} else {
Ok(val.to_string())
}
}
Value::Float { val, .. } => Ok(ObviousFloat(*val).to_string()),
Value::Int { val, .. } => Ok(val.to_string()),
Value::List { vals, .. } => {
let headers = get_columns(vals);
@ -213,43 +205,7 @@ fn value_to_string(
Value::Nothing { .. } => Ok("null".to_string()),
Value::Range { val, .. } => match **val {
Range::IntRange(range) => Ok(range.to_string()),
Range::FloatRange(range) => {
let start = value_to_string(
engine_state,
&Value::float(range.start(), span),
span,
depth + 1,
indent,
serialize_types,
)?;
match range.end() {
Bound::Included(end) => Ok(format!(
"{}..{}",
start,
value_to_string(
engine_state,
&Value::float(end, span),
span,
depth + 1,
indent,
serialize_types,
)?
)),
Bound::Excluded(end) => Ok(format!(
"{}..<{}",
start,
value_to_string(
engine_state,
&Value::float(end, span),
span,
depth + 1,
indent,
serialize_types,
)?
)),
Bound::Unbounded => Ok(format!("{start}..",)),
}
}
Range::FloatRange(range) => Ok(range.to_string()),
},
Value::Record { val, .. } => {
let mut collection = vec![];