mirror of
https://github.com/nushell/nushell.git
synced 2025-01-09 07:48:14 +01:00
commit
caa6236f1f
@ -403,6 +403,38 @@ mod range {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_float_range() {
|
||||||
|
let engine_state = EngineState::new();
|
||||||
|
let mut working_set = StateWorkingSet::new(&engine_state);
|
||||||
|
|
||||||
|
let (block, err) = parse(&mut working_set, None, b"2.0..4.0..10.0", true);
|
||||||
|
|
||||||
|
assert!(err.is_none());
|
||||||
|
assert!(block.len() == 1);
|
||||||
|
match &block[0] {
|
||||||
|
Statement::Pipeline(Pipeline { expressions }) => {
|
||||||
|
assert!(expressions.len() == 1);
|
||||||
|
assert!(matches!(
|
||||||
|
expressions[0],
|
||||||
|
Expression {
|
||||||
|
expr: Expr::Range(
|
||||||
|
Some(_),
|
||||||
|
Some(_),
|
||||||
|
Some(_),
|
||||||
|
RangeOperator {
|
||||||
|
inclusion: RangeInclusion::Inclusive,
|
||||||
|
..
|
||||||
|
}
|
||||||
|
),
|
||||||
|
..
|
||||||
|
}
|
||||||
|
))
|
||||||
|
}
|
||||||
|
_ => panic!("No match"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bad_parse_does_crash() {
|
fn bad_parse_does_crash() {
|
||||||
let engine_state = EngineState::new();
|
let engine_state = EngineState::new();
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{RangeInclusion, RangeOperator},
|
ast::{RangeInclusion, RangeOperator},
|
||||||
*,
|
*,
|
||||||
@ -150,29 +152,50 @@ impl RangeIterator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare two floating point numbers. The decision interval for equality is dynamically scaled
|
||||||
|
// as the value being compared increases in magnitude.
|
||||||
|
fn compare_floats(val: f64, other: f64) -> Option<Ordering> {
|
||||||
|
let prec = f64::EPSILON.max(val.abs() * f64::EPSILON);
|
||||||
|
|
||||||
|
if (other - val).abs() < prec {
|
||||||
|
return Some(Ordering::Equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
val.partial_cmp(&other)
|
||||||
|
}
|
||||||
|
|
||||||
impl Iterator for RangeIterator {
|
impl Iterator for RangeIterator {
|
||||||
type Item = Value;
|
type Item = Value;
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
use std::cmp::Ordering;
|
|
||||||
if self.done {
|
if self.done {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ordering = if matches!(self.end, Value::Nothing { .. }) {
|
let ordering = if matches!(self.end, Value::Nothing { .. }) {
|
||||||
Ordering::Less
|
Some(Ordering::Less)
|
||||||
} else {
|
} else {
|
||||||
match (&self.curr, &self.end) {
|
match (&self.curr, &self.end) {
|
||||||
(Value::Int { val: curr, .. }, Value::Int { val: end, .. }) => curr.cmp(end),
|
(Value::Int { val: curr, .. }, Value::Int { val: end, .. }) => Some(curr.cmp(end)),
|
||||||
// (Value::Float { val: curr, .. }, Value::Float { val: end, .. }) => curr.cmp(end),
|
(Value::Float { val: curr, .. }, Value::Float { val: end, .. }) => {
|
||||||
// (Value::Float { val: curr, .. }, Value::Int { val: end, .. }) => curr.cmp(end),
|
compare_floats(*curr, *end)
|
||||||
// (Value::Int { val: curr, .. }, Value::Float { val: end, .. }) => curr.cmp(end),
|
}
|
||||||
_ => {
|
(Value::Float { val: curr, .. }, Value::Int { val: end, .. }) => {
|
||||||
|
compare_floats(*curr, *end as f64)
|
||||||
|
}
|
||||||
|
(Value::Int { val: curr, .. }, Value::Float { val: end, .. }) => {
|
||||||
|
compare_floats(*curr as f64, *end)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ordering = if let Some(ord) = ordering {
|
||||||
|
ord
|
||||||
|
} else {
|
||||||
self.done = true;
|
self.done = true;
|
||||||
return Some(Value::Error {
|
return Some(Value::Error {
|
||||||
error: ShellError::CannotCreateRange(self.span),
|
error: ShellError::CannotCreateRange(self.span),
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let desired_ordering = if self.moves_up {
|
let desired_ordering = if self.moves_up {
|
||||||
|
Loading…
Reference in New Issue
Block a user