forked from extern/nushell
allow decimals as a range boundary (#2509)
This commit is contained in:
parent
2c5939dc7d
commit
d9ae66791a
@ -81,7 +81,6 @@ struct RangeIterator {
|
||||
end: Primitive,
|
||||
tag: Tag,
|
||||
is_end_inclusive: bool,
|
||||
is_done: bool,
|
||||
}
|
||||
|
||||
impl RangeIterator {
|
||||
@ -96,7 +95,6 @@ impl RangeIterator {
|
||||
end: range.to.0.item,
|
||||
tag,
|
||||
is_end_inclusive: matches!(range.to.1, RangeInclusion::Inclusive),
|
||||
is_done: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,14 +102,40 @@ impl RangeIterator {
|
||||
impl Iterator for RangeIterator {
|
||||
type Item = Result<ReturnSuccess, ShellError>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.curr != self.end {
|
||||
let ordering = if self.end == Primitive::Nothing {
|
||||
Ordering::Less
|
||||
} else {
|
||||
let result =
|
||||
nu_data::base::coerce_compare_primitive(&self.curr, &self.end).map_err(|_| {
|
||||
ShellError::labeled_error(
|
||||
"Cannot create range",
|
||||
"unsupported range",
|
||||
self.tag.span,
|
||||
)
|
||||
});
|
||||
|
||||
if let Err(result) = result {
|
||||
return Some(Err(result));
|
||||
}
|
||||
|
||||
let result = result
|
||||
.expect("Internal error: the error case was already protected, but that failed");
|
||||
|
||||
result.compare()
|
||||
};
|
||||
|
||||
use std::cmp::Ordering;
|
||||
|
||||
if (ordering == Ordering::Less) || (self.is_end_inclusive && ordering == Ordering::Equal) {
|
||||
let output = UntaggedValue::Primitive(self.curr.clone()).into_value(self.tag.clone());
|
||||
|
||||
self.curr = match nu_data::value::compute_values(
|
||||
let next_value = nu_data::value::compute_values(
|
||||
Operator::Plus,
|
||||
&UntaggedValue::Primitive(self.curr.clone()),
|
||||
&UntaggedValue::int(1),
|
||||
) {
|
||||
);
|
||||
|
||||
self.curr = match next_value {
|
||||
Ok(result) => match result {
|
||||
UntaggedValue::Primitive(p) => p,
|
||||
_ => {
|
||||
@ -128,11 +152,6 @@ impl Iterator for RangeIterator {
|
||||
}
|
||||
};
|
||||
Some(ReturnSuccess::value(output))
|
||||
} else if self.is_end_inclusive && !self.is_done {
|
||||
self.is_done = true;
|
||||
Some(ReturnSuccess::value(
|
||||
UntaggedValue::Primitive(self.curr.clone()).into_value(self.tag.clone()),
|
||||
))
|
||||
} else {
|
||||
// TODO: add inclusive/exclusive ranges
|
||||
None
|
||||
|
@ -126,7 +126,7 @@ pub fn coerce_compare(
|
||||
}
|
||||
}
|
||||
|
||||
fn coerce_compare_primitive(
|
||||
pub fn coerce_compare_primitive(
|
||||
left: &Primitive,
|
||||
right: &Primitive,
|
||||
) -> Result<CompareValues, (&'static str, &'static str)> {
|
||||
|
@ -502,6 +502,18 @@ fn range_with_open_right() {
|
||||
assert_eq!(actual.out, "95");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_with_mixed_types() {
|
||||
let actual = nu!(
|
||||
cwd: ".",
|
||||
r#"
|
||||
echo 1..10.5 | math sum
|
||||
"#
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "55");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_expansion_of_tables() {
|
||||
let actual = nu!(
|
||||
|
Loading…
Reference in New Issue
Block a user