mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
RangeIterator can also go down (#2913)
This commit is contained in:
parent
3be198d2f5
commit
dff85a7f70
@ -76,6 +76,7 @@ struct RangeIterator {
|
|||||||
end: Primitive,
|
end: Primitive,
|
||||||
tag: Tag,
|
tag: Tag,
|
||||||
is_end_inclusive: bool,
|
is_end_inclusive: bool,
|
||||||
|
moves_up: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RangeIterator {
|
impl RangeIterator {
|
||||||
@ -85,9 +86,15 @@ impl RangeIterator {
|
|||||||
x => x,
|
x => x,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let end = match range.to.0.item {
|
||||||
|
Primitive::Nothing => Primitive::Int(u64::MAX.into()),
|
||||||
|
x => x,
|
||||||
|
};
|
||||||
|
|
||||||
RangeIterator {
|
RangeIterator {
|
||||||
|
moves_up: start <= end,
|
||||||
curr: start,
|
curr: start,
|
||||||
end: range.to.0.item,
|
end,
|
||||||
tag,
|
tag,
|
||||||
is_end_inclusive: matches!(range.to.1, RangeInclusion::Inclusive),
|
is_end_inclusive: matches!(range.to.1, RangeInclusion::Inclusive),
|
||||||
}
|
}
|
||||||
@ -121,7 +128,9 @@ impl Iterator for RangeIterator {
|
|||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
if (ordering == Ordering::Less) || (self.is_end_inclusive && ordering == Ordering::Equal) {
|
if self.moves_up
|
||||||
|
&& (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());
|
||||||
|
|
||||||
let next_value = nu_data::value::compute_values(
|
let next_value = nu_data::value::compute_values(
|
||||||
@ -130,6 +139,35 @@ impl Iterator for RangeIterator {
|
|||||||
&UntaggedValue::int(1),
|
&UntaggedValue::int(1),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.curr = match next_value {
|
||||||
|
Ok(result) => match result {
|
||||||
|
UntaggedValue::Primitive(p) => p,
|
||||||
|
_ => {
|
||||||
|
return Some(Err(ShellError::unimplemented(
|
||||||
|
"Internal error: expected a primitive result from increment",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err((left_type, right_type)) => {
|
||||||
|
return Some(Err(ShellError::coerce_error(
|
||||||
|
left_type.spanned(self.tag.span),
|
||||||
|
right_type.spanned(self.tag.span),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(ReturnSuccess::value(output))
|
||||||
|
} else if !self.moves_up
|
||||||
|
&& (ordering == Ordering::Greater
|
||||||
|
|| self.is_end_inclusive && ordering == Ordering::Equal)
|
||||||
|
{
|
||||||
|
let output = UntaggedValue::Primitive(self.curr.clone()).into_value(self.tag.clone());
|
||||||
|
|
||||||
|
let next_value = nu_data::value::compute_values(
|
||||||
|
Operator::Plus,
|
||||||
|
&UntaggedValue::Primitive(self.curr.clone()),
|
||||||
|
&UntaggedValue::int(-1),
|
||||||
|
);
|
||||||
|
|
||||||
self.curr = match next_value {
|
self.curr = match next_value {
|
||||||
Ok(result) => match result {
|
Ok(result) => match result {
|
||||||
UntaggedValue::Primitive(p) => p,
|
UntaggedValue::Primitive(p) => p,
|
||||||
@ -148,7 +186,6 @@ impl Iterator for RangeIterator {
|
|||||||
};
|
};
|
||||||
Some(ReturnSuccess::value(output))
|
Some(ReturnSuccess::value(output))
|
||||||
} else {
|
} else {
|
||||||
// TODO: add inclusive/exclusive ranges
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,3 +11,51 @@ fn echo_range_is_lazy() {
|
|||||||
|
|
||||||
assert_eq!(actual.out, "[1,2,3]");
|
assert_eq!(actual.out, "[1,2,3]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn echo_range_handles_inclusive() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
echo 1..3 | to json
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "[1,2,3]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn echo_range_handles_exclusive() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
echo 1..<3 | to json
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "[1,2]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn echo_range_handles_inclusive_down() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
echo 3..1 | to json
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "[3,2,1]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn echo_range_handles_exclusive_down() {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: "tests/fixtures/formats", pipeline(
|
||||||
|
r#"
|
||||||
|
echo 3..<1 | to json
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual.out, "[3,2]");
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user