allow decimals as a range boundary (#2509)

This commit is contained in:
Jonathan Turner 2020-09-08 05:30:11 +12:00 committed by GitHub
parent 2c5939dc7d
commit d9ae66791a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 11 deletions

View File

@ -81,7 +81,6 @@ struct RangeIterator {
end: Primitive, end: Primitive,
tag: Tag, tag: Tag,
is_end_inclusive: bool, is_end_inclusive: bool,
is_done: bool,
} }
impl RangeIterator { impl RangeIterator {
@ -96,7 +95,6 @@ impl RangeIterator {
end: range.to.0.item, end: range.to.0.item,
tag, tag,
is_end_inclusive: matches!(range.to.1, RangeInclusion::Inclusive), is_end_inclusive: matches!(range.to.1, RangeInclusion::Inclusive),
is_done: false,
} }
} }
} }
@ -104,14 +102,40 @@ impl RangeIterator {
impl Iterator for RangeIterator { impl Iterator for RangeIterator {
type Item = Result<ReturnSuccess, ShellError>; type Item = Result<ReturnSuccess, ShellError>;
fn next(&mut self) -> Option<Self::Item> { 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()); 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, Operator::Plus,
&UntaggedValue::Primitive(self.curr.clone()), &UntaggedValue::Primitive(self.curr.clone()),
&UntaggedValue::int(1), &UntaggedValue::int(1),
) { );
self.curr = match next_value {
Ok(result) => match result { Ok(result) => match result {
UntaggedValue::Primitive(p) => p, UntaggedValue::Primitive(p) => p,
_ => { _ => {
@ -128,11 +152,6 @@ impl Iterator for RangeIterator {
} }
}; };
Some(ReturnSuccess::value(output)) 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 { } else {
// TODO: add inclusive/exclusive ranges // TODO: add inclusive/exclusive ranges
None None

View File

@ -126,7 +126,7 @@ pub fn coerce_compare(
} }
} }
fn coerce_compare_primitive( pub fn coerce_compare_primitive(
left: &Primitive, left: &Primitive,
right: &Primitive, right: &Primitive,
) -> Result<CompareValues, (&'static str, &'static str)> { ) -> Result<CompareValues, (&'static str, &'static str)> {

View File

@ -502,6 +502,18 @@ fn range_with_open_right() {
assert_eq!(actual.out, "95"); 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] #[test]
fn it_expansion_of_tables() { fn it_expansion_of_tables() {
let actual = nu!( let actual = nu!(