mirror of
https://github.com/nushell/nushell.git
synced 2025-08-13 18:37:35 +02:00
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:
16
crates/nu-protocol/src/value/format.rs
Normal file
16
crates/nu-protocol/src/value/format.rs
Normal file
@ -0,0 +1,16 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
/// A f64 wrapper that formats whole numbers with a decimal point.
|
||||
pub struct ObviousFloat(pub f64);
|
||||
|
||||
impl Display for ObviousFloat {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let val = self.0;
|
||||
// This serialises these as 'nan', 'inf' and '-inf', respectively.
|
||||
if val.round() == val && val.is_finite() {
|
||||
write!(f, "{}.0", val)
|
||||
} else {
|
||||
write!(f, "{}", val)
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ mod range;
|
||||
#[cfg(test)]
|
||||
mod test_derive;
|
||||
|
||||
pub mod format;
|
||||
pub mod record;
|
||||
pub use custom_value::CustomValue;
|
||||
pub use duration::*;
|
||||
|
@ -183,12 +183,14 @@ mod int_range {
|
||||
|
||||
impl Display for IntRange {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// what about self.step?
|
||||
let start = self.start;
|
||||
write!(f, "{}..", self.start)?;
|
||||
if self.step != 1 {
|
||||
write!(f, "{}..", self.start + self.step)?;
|
||||
}
|
||||
match self.end {
|
||||
Bound::Included(end) => write!(f, "{start}..{end}"),
|
||||
Bound::Excluded(end) => write!(f, "{start}..<{end}"),
|
||||
Bound::Unbounded => write!(f, "{start}.."),
|
||||
Bound::Included(end) => write!(f, "{end}"),
|
||||
Bound::Excluded(end) => write!(f, "<{end}"),
|
||||
Bound::Unbounded => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -228,7 +230,10 @@ mod int_range {
|
||||
}
|
||||
|
||||
mod float_range {
|
||||
use crate::{ast::RangeInclusion, IntRange, Range, ShellError, Signals, Span, Value};
|
||||
use crate::{
|
||||
ast::RangeInclusion, format::ObviousFloat, IntRange, Range, ShellError, Signals, Span,
|
||||
Value,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{cmp::Ordering, fmt::Display, ops::Bound};
|
||||
|
||||
@ -434,12 +439,14 @@ mod float_range {
|
||||
|
||||
impl Display for FloatRange {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
// what about self.step?
|
||||
let start = self.start;
|
||||
write!(f, "{}..", ObviousFloat(self.start))?;
|
||||
if self.step != 1f64 {
|
||||
write!(f, "{}..", ObviousFloat(self.start + self.step))?;
|
||||
}
|
||||
match self.end {
|
||||
Bound::Included(end) => write!(f, "{start}..{end}"),
|
||||
Bound::Excluded(end) => write!(f, "{start}..<{end}"),
|
||||
Bound::Unbounded => write!(f, "{start}.."),
|
||||
Bound::Included(end) => write!(f, "{}", ObviousFloat(end)),
|
||||
Bound::Excluded(end) => write!(f, "<{}", ObviousFloat(end)),
|
||||
Bound::Unbounded => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user