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,
|
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
|
||||||
|
@ -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)> {
|
||||||
|
@ -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!(
|
||||||
|
Loading…
Reference in New Issue
Block a user