mirror of
https://github.com/nushell/nushell.git
synced 2025-05-06 19:14:25 +02:00
make seq more nu-like by returning numbers when possible (#3409)
This commit is contained in:
parent
b93b80ccaa
commit
e73491441a
@ -1,7 +1,7 @@
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use nu_engine::WholeStreamCommand;
|
use nu_engine::WholeStreamCommand;
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::value::StrExt;
|
use nu_protocol::value::{DecimalExt, I64Ext, StrExt};
|
||||||
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::Tagged;
|
use nu_source::Tagged;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
@ -57,16 +57,33 @@ impl WholeStreamCommand for Seq {
|
|||||||
description: "sequence 1 to 10 with newline separator",
|
description: "sequence 1 to 10 with newline separator",
|
||||||
example: "seq 1 10",
|
example: "seq 1 10",
|
||||||
result: Some(vec![
|
result: Some(vec![
|
||||||
UntaggedValue::string("1").into(),
|
UntaggedValue::int(1).into(),
|
||||||
UntaggedValue::string("2").into(),
|
UntaggedValue::int(2).into(),
|
||||||
UntaggedValue::string("3").into(),
|
UntaggedValue::int(3).into(),
|
||||||
UntaggedValue::string("4").into(),
|
UntaggedValue::int(4).into(),
|
||||||
UntaggedValue::string("5").into(),
|
UntaggedValue::int(5).into(),
|
||||||
UntaggedValue::string("6").into(),
|
UntaggedValue::int(6).into(),
|
||||||
UntaggedValue::string("7").into(),
|
UntaggedValue::int(7).into(),
|
||||||
UntaggedValue::string("8").into(),
|
UntaggedValue::int(8).into(),
|
||||||
UntaggedValue::string("9").into(),
|
UntaggedValue::int(9).into(),
|
||||||
UntaggedValue::string("10").into(),
|
UntaggedValue::int(10).into(),
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
Example {
|
||||||
|
description: "sequence 1.0 to 2.0 by 0.1s with newline separator",
|
||||||
|
example: "seq 1.0 0.1 2.0",
|
||||||
|
result: Some(vec![
|
||||||
|
UntaggedValue::decimal_from_float(1.0000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.1000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.2000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.3000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.4000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.5000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.6000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.7000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.8000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(1.9000, Span::default()).into(),
|
||||||
|
UntaggedValue::decimal_from_float(2.0000, Span::default()).into(),
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
Example {
|
Example {
|
||||||
@ -291,8 +308,19 @@ fn print_seq(
|
|||||||
) -> OutputStream {
|
) -> OutputStream {
|
||||||
let mut i = 0isize;
|
let mut i = 0isize;
|
||||||
let mut value = first + i as f64 * step;
|
let mut value = first + i as f64 * step;
|
||||||
|
// for string output
|
||||||
let mut ret_str = "".to_owned();
|
let mut ret_str = "".to_owned();
|
||||||
|
// for number output
|
||||||
|
let mut ret_num = vec![];
|
||||||
|
// If the separator and terminator are line endings we can convert to numbers
|
||||||
|
let use_num =
|
||||||
|
(separator == "\n" || separator == "\r") && (terminator == "\n" || terminator == "\r");
|
||||||
|
|
||||||
while !done_printing(value, step, last) {
|
while !done_printing(value, step, last) {
|
||||||
|
if use_num {
|
||||||
|
ret_num.push(value);
|
||||||
|
} else {
|
||||||
|
// formatting for string output with potential padding
|
||||||
let istr = format!("{:.*}", largest_dec, value);
|
let istr = format!("{:.*}", largest_dec, value);
|
||||||
let ilen = istr.len();
|
let ilen = istr.len();
|
||||||
let before_dec = istr.find('.').unwrap_or(ilen);
|
let before_dec = istr.find('.').unwrap_or(ilen);
|
||||||
@ -302,6 +330,7 @@ fn print_seq(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret_str.push_str(&istr);
|
ret_str.push_str(&istr);
|
||||||
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
value = first + i as f64 * step;
|
value = first + i as f64 * step;
|
||||||
if !done_printing(value, step, last) {
|
if !done_printing(value, step, last) {
|
||||||
@ -309,13 +338,44 @@ fn print_seq(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first >= last && step < 0f64) || (first <= last && step > 0f64) {
|
if !use_num && ((first >= last && step < 0f64) || (first <= last && step > 0f64)) {
|
||||||
ret_str.push_str(&terminator);
|
ret_str.push_str(&terminator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if use_num {
|
||||||
|
// we'd like to keep the datatype the same for the output, so check
|
||||||
|
// and see if any of the output is really decimals, and if it is
|
||||||
|
// we'll make the entire output decimals
|
||||||
|
let contains_decimals = vec_contains_decimals(&ret_num);
|
||||||
|
let rows: Vec<Value> = ret_num
|
||||||
|
.iter()
|
||||||
|
.map(|v| {
|
||||||
|
if contains_decimals {
|
||||||
|
v.to_value_create_tag()
|
||||||
|
} else {
|
||||||
|
let vi64 = *v as i64;
|
||||||
|
vi64.to_value_create_tag()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
(rows.into_iter()).to_output_stream()
|
||||||
|
} else {
|
||||||
let rows: Vec<Value> = ret_str
|
let rows: Vec<Value> = ret_str
|
||||||
.lines()
|
.lines()
|
||||||
.map(|v| v.to_str_value_create_tag())
|
.map(|v| v.to_str_value_create_tag())
|
||||||
.collect();
|
.collect();
|
||||||
(rows.into_iter()).to_output_stream()
|
(rows.into_iter()).to_output_stream()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vec_contains_decimals(array: &[f64]) -> bool {
|
||||||
|
let mut found_decimal = false;
|
||||||
|
for x in array {
|
||||||
|
if x.fract() != 0.0 {
|
||||||
|
found_decimal = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found_decimal
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user