diff --git a/crates/nu-command/src/commands/range.rs b/crates/nu-command/src/commands/range.rs index 364fb0a15..aae93d0ec 100644 --- a/crates/nu-command/src/commands/range.rs +++ b/crates/nu-command/src/commands/range.rs @@ -1,13 +1,10 @@ use crate::prelude::*; -use nu_engine::deserializer::NumericRange; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; -use nu_protocol::{RangeInclusion, ReturnSuccess, Signature, SyntaxShape}; -use nu_source::Tagged; +use nu_protocol::{RangeInclusion, Signature, SyntaxShape, Value}; -#[derive(Deserialize)] struct RangeArgs { - area: Tagged, + range: nu_protocol::Range, } pub struct Range; @@ -19,7 +16,7 @@ impl WholeStreamCommand for Range { fn signature(&self) -> Signature { Signature::build("range").required( - "rows ", + "rows", SyntaxShape::Range, "range of rows to return: Eg) 4..7 (=> from 4 to 7)", ) @@ -29,25 +26,35 @@ impl WholeStreamCommand for Range { "Return only the selected rows." } - fn run_with_actions(&self, args: CommandArgs) -> Result { + fn run(&self, args: CommandArgs) -> Result { range(args) } } -fn range(args: CommandArgs) -> Result { - let (RangeArgs { area }, input) = args.process()?; - let range = area.item; - let (from, left_inclusive) = range.from; - let (to, right_inclusive) = range.to; - let from = from.map(|from| *from as usize).unwrap_or(0).saturating_add( - if left_inclusive == RangeInclusion::Inclusive { +fn range(args: CommandArgs) -> Result { + let args = args.evaluate_once()?; + let cmd_args = RangeArgs { + range: args.req(0)?, + }; + + let (from, left_inclusive) = cmd_args.range.from; + let (to, right_inclusive) = cmd_args.range.to; + let from_span = from.span; + let to_span = to.span; + + let from = from + .map(|from| from.as_usize(from_span)) + .item + .unwrap_or(0) + .saturating_add(if left_inclusive == RangeInclusion::Inclusive { 0 } else { 1 - }, - ); + }); + let to = to - .map(|to| *to as usize) + .map(|to| to.as_usize(to_span)) + .item .unwrap_or(usize::MAX) .saturating_sub(if right_inclusive == RangeInclusion::Inclusive { 0 @@ -55,11 +62,11 @@ fn range(args: CommandArgs) -> Result { 1 }); - Ok(input - .skip(from) - .take(to - from + 1) - .map(ReturnSuccess::value) - .to_action_stream()) + if from > to { + Ok(OutputStream::one(Value::nothing())) + } else { + Ok(args.input.skip(from).take(to - from + 1).to_output_stream()) + } } #[cfg(test)] diff --git a/crates/nu-engine/src/from_value.rs b/crates/nu-engine/src/from_value.rs index 55477706f..ea5dda67b 100644 --- a/crates/nu-engine/src/from_value.rs +++ b/crates/nu-engine/src/from_value.rs @@ -40,6 +40,7 @@ impl FromValue for num_bigint::BigInt { } } } + impl FromValue for Tagged { fn from_value(v: &Value) -> Result { let tag = v.tag.clone();