forked from extern/nushell
# Description This is to resolve the issue [8614](https://github.com/nushell/nushell/issues/8614). It allows the parsing of the mu (µ) character for durations, so you can type `10µs`, and it correctly outputs, whilst maintaining the current `us` parsing as well. It also forces `durations` to be entered in lower case. ![image](https://user-images.githubusercontent.com/44570273/228217360-57ebc902-cec5-4683-910e-0b18fbe160b1.png) (The bottom one `1sec | into duration --convert us` looks like an existing bug, where converting to `us` outputs `us` rather than `µs`) # User-Facing Changes Allows the user to parse durations in µs Forces `durations` to be entered in lower case rather than any case, and will error if not in lower case. # Tests + Formatting Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` # After Submitting If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. --------- Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
parent
e9c17daecd
commit
bc6948dc89
@ -145,6 +145,22 @@ impl Command for SubCommand {
|
||||
span,
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Convert µs duration to the requested duration as a string",
|
||||
example: "1000000µs | into duration --convert sec",
|
||||
result: Some(Value::String {
|
||||
val: "1 sec".to_string(),
|
||||
span,
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Convert duration to the µs duration as a string",
|
||||
example: "1sec | into duration --convert µs",
|
||||
result: Some(Value::String {
|
||||
val: "1000000 µs".to_string(),
|
||||
span,
|
||||
}),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -197,6 +213,8 @@ fn convert_str_from_unit_to_unit(
|
||||
match (from_unit, to_unit) {
|
||||
("ns", "ns") => Ok(val as f64),
|
||||
("ns", "us") => Ok(val as f64 / 1000.0),
|
||||
("ns", "µs") => Ok(val as f64 / 1000.0), // Micro sign
|
||||
("ns", "μs") => Ok(val as f64 / 1000.0), // Greek small letter
|
||||
("ns", "ms") => Ok(val as f64 / 1000.0 / 1000.0),
|
||||
("ns", "sec") => Ok(val as f64 / 1000.0 / 1000.0 / 1000.0),
|
||||
("ns", "min") => Ok(val as f64 / 1000.0 / 1000.0 / 1000.0 / 60.0),
|
||||
@ -211,6 +229,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("us", "ns") => Ok(val as f64 * 1000.0),
|
||||
("us", "us") => Ok(val as f64),
|
||||
("us", "µs") => Ok(val as f64), // Micro sign
|
||||
("us", "μs") => Ok(val as f64), // Greek small letter
|
||||
("us", "ms") => Ok(val as f64 / 1000.0),
|
||||
("us", "sec") => Ok(val as f64 / 1000.0 / 1000.0),
|
||||
("us", "min") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0),
|
||||
@ -221,8 +241,40 @@ fn convert_str_from_unit_to_unit(
|
||||
("us", "yr") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 365.0),
|
||||
("us", "dec") => Ok(val as f64 / 10.0 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 365.0),
|
||||
|
||||
// Micro sign
|
||||
("µs", "ns") => Ok(val as f64 * 1000.0),
|
||||
("µs", "us") => Ok(val as f64),
|
||||
("µs", "µs") => Ok(val as f64), // Micro sign
|
||||
("µs", "μs") => Ok(val as f64), // Greek small letter
|
||||
("µs", "ms") => Ok(val as f64 / 1000.0),
|
||||
("µs", "sec") => Ok(val as f64 / 1000.0 / 1000.0),
|
||||
("µs", "min") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0),
|
||||
("µs", "hr") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0),
|
||||
("µs", "day") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0),
|
||||
("µs", "wk") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 7.0),
|
||||
("µs", "month") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 30.0),
|
||||
("µs", "yr") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 365.0),
|
||||
("µs", "dec") => Ok(val as f64 / 10.0 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 365.0),
|
||||
|
||||
// Greek small letter
|
||||
("μs", "ns") => Ok(val as f64 * 1000.0),
|
||||
("μs", "us") => Ok(val as f64),
|
||||
("μs", "µs") => Ok(val as f64), // Micro sign
|
||||
("μs", "μs") => Ok(val as f64), // Greek small letter
|
||||
("μs", "ms") => Ok(val as f64 / 1000.0),
|
||||
("μs", "sec") => Ok(val as f64 / 1000.0 / 1000.0),
|
||||
("μs", "min") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0),
|
||||
("μs", "hr") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0),
|
||||
("μs", "day") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0),
|
||||
("μs", "wk") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 7.0),
|
||||
("μs", "month") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 30.0),
|
||||
("μs", "yr") => Ok(val as f64 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 365.0),
|
||||
("μs", "dec") => Ok(val as f64 / 10.0 / 1000.0 / 1000.0 / 60.0 / 60.0 / 24.0 / 365.0),
|
||||
|
||||
("ms", "ns") => Ok(val as f64 * 1000.0 * 1000.0),
|
||||
("ms", "us") => Ok(val as f64 * 1000.0),
|
||||
("ms", "µs") => Ok(val as f64 * 1000.0), // Micro sign
|
||||
("ms", "μs") => Ok(val as f64 * 1000.0), // Greek small letter
|
||||
("ms", "ms") => Ok(val as f64),
|
||||
("ms", "sec") => Ok(val as f64 / 1000.0),
|
||||
("ms", "min") => Ok(val as f64 / 1000.0 / 60.0),
|
||||
@ -235,6 +287,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("sec", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0),
|
||||
("sec", "us") => Ok(val as f64 * 1000.0 * 1000.0),
|
||||
("sec", "µs") => Ok(val as f64 * 1000.0 * 1000.0), // Micro sign
|
||||
("sec", "μs") => Ok(val as f64 * 1000.0 * 1000.0), // Greek small letter
|
||||
("sec", "ms") => Ok(val as f64 * 1000.0),
|
||||
("sec", "sec") => Ok(val as f64),
|
||||
("sec", "min") => Ok(val as f64 / 60.0),
|
||||
@ -247,6 +301,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("min", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0 * 60.0),
|
||||
("min", "us") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0),
|
||||
("min", "µs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0), // Micro sign
|
||||
("min", "μs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0), // Greek small letter
|
||||
("min", "ms") => Ok(val as f64 * 1000.0 * 60.0),
|
||||
("min", "sec") => Ok(val as f64 * 60.0),
|
||||
("min", "min") => Ok(val as f64),
|
||||
@ -259,6 +315,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("hr", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0 * 60.0 * 60.0),
|
||||
("hr", "us") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0),
|
||||
("hr", "µs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0), // Micro sign
|
||||
("hr", "μs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0), // Greek small letter
|
||||
("hr", "ms") => Ok(val as f64 * 1000.0 * 60.0 * 60.0),
|
||||
("hr", "sec") => Ok(val as f64 * 60.0 * 60.0),
|
||||
("hr", "min") => Ok(val as f64 * 60.0),
|
||||
@ -271,6 +329,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("day", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0),
|
||||
("day", "us") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0),
|
||||
("day", "µs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0), // Micro sign
|
||||
("day", "μs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0), // Greek small letter
|
||||
("day", "ms") => Ok(val as f64 * 1000.0 * 60.0 * 60.0 * 24.0),
|
||||
("day", "sec") => Ok(val as f64 * 60.0 * 60.0 * 24.0),
|
||||
("day", "min") => Ok(val as f64 * 60.0 * 24.0),
|
||||
@ -283,6 +343,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("wk", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 7.0),
|
||||
("wk", "us") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 7.0),
|
||||
("wk", "µs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 7.0), // Micro sign
|
||||
("wk", "μs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 7.0), // Greek small letter
|
||||
("wk", "ms") => Ok(val as f64 * 1000.0 * 60.0 * 60.0 * 24.0 * 7.0),
|
||||
("wk", "sec") => Ok(val as f64 * 60.0 * 60.0 * 24.0 * 7.0),
|
||||
("wk", "min") => Ok(val as f64 * 60.0 * 24.0 * 7.0),
|
||||
@ -295,6 +357,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("month", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 30.0),
|
||||
("month", "us") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 30.0),
|
||||
("month", "µs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 30.0), // Micro sign
|
||||
("month", "μs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 30.0), // Greek small letter
|
||||
("month", "ms") => Ok(val as f64 * 1000.0 * 60.0 * 60.0 * 24.0 * 30.0),
|
||||
("month", "sec") => Ok(val as f64 * 60.0 * 60.0 * 24.0 * 30.0),
|
||||
("month", "min") => Ok(val as f64 * 60.0 * 24.0 * 30.0),
|
||||
@ -307,6 +371,8 @@ fn convert_str_from_unit_to_unit(
|
||||
|
||||
("yr", "ns") => Ok(val as f64 * 1000.0 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 365.0),
|
||||
("yr", "us") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 365.0),
|
||||
("yr", "µs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 365.0), // Micro sign
|
||||
("yr", "μs") => Ok(val as f64 * 1000.0 * 1000.0 * 60.0 * 60.0 * 24.0 * 365.0), // Greek small letter
|
||||
("yr", "ms") => Ok(val as f64 * 1000.0 * 60.0 * 60.0 * 24.0 * 365.0),
|
||||
("yr", "sec") => Ok(val as f64 * 60.0 * 60.0 * 24.0 * 365.0),
|
||||
("yr", "min") => Ok(val as f64 * 60.0 * 24.0 * 365.0),
|
||||
@ -324,7 +390,7 @@ fn convert_str_from_unit_to_unit(
|
||||
dst_span: span,
|
||||
src_span: value_span,
|
||||
help: Some(
|
||||
"supported units are ns, us, ms, sec, min, hr, day, wk, month, yr and dec"
|
||||
"supported units are ns, us/µs, ms, sec, min, hr, day, wk, month, yr, and dec"
|
||||
.to_string(),
|
||||
),
|
||||
}),
|
||||
@ -357,7 +423,8 @@ fn string_to_duration(s: &str, span: Span, value_span: Span) -> Result<i64, Shel
|
||||
dst_span: span,
|
||||
src_span: value_span,
|
||||
help: Some(
|
||||
"supported units are ns, us, ms, sec, min, hr, day, wk, month, yr and dec".to_string(),
|
||||
"supported units are ns, us/µs, ms, sec, min, hr, day, wk, month, yr, and dec"
|
||||
.to_string(),
|
||||
),
|
||||
})
|
||||
}
|
||||
@ -393,7 +460,8 @@ fn string_to_unit_duration(
|
||||
dst_span: span,
|
||||
src_span: value_span,
|
||||
help: Some(
|
||||
"supported units are ns, us, ms, sec, min, hr, day, wk, month, yr and dec".to_string(),
|
||||
"supported units are ns, us/µs, ms, sec, min, hr, day, wk, month, yr, and dec"
|
||||
.to_string(),
|
||||
),
|
||||
})
|
||||
}
|
||||
@ -536,6 +604,34 @@ mod test {
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turns_micro_sign_s_to_duration() {
|
||||
let span = Span::new(0, 2);
|
||||
let word = Value::test_string("4\u{00B5}s");
|
||||
let expected = Value::Duration {
|
||||
val: 4 * 1000,
|
||||
span,
|
||||
};
|
||||
let convert_duration = None;
|
||||
|
||||
let actual = action(&word, &convert_duration, 2, span);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turns_mu_s_to_duration() {
|
||||
let span = Span::new(0, 2);
|
||||
let word = Value::test_string("4\u{03BC}s");
|
||||
let expected = Value::Duration {
|
||||
val: 4 * 1000,
|
||||
span,
|
||||
};
|
||||
let convert_duration = None;
|
||||
|
||||
let actual = action(&word, &convert_duration, 2, span);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turns_ms_to_duration() {
|
||||
let span = Span::new(0, 2);
|
||||
|
@ -2604,24 +2604,32 @@ pub fn parse_duration_bytes(num_with_unit_bytes: &[u8], span: Span) -> Option<Ex
|
||||
}
|
||||
|
||||
let num_with_unit = String::from_utf8_lossy(num_with_unit_bytes).to_string();
|
||||
let uppercase_num_with_unit = num_with_unit.to_uppercase();
|
||||
let unit_groups = [
|
||||
(Unit::Nanosecond, "NS", None),
|
||||
(Unit::Microsecond, "US", Some((Unit::Nanosecond, 1000))),
|
||||
(Unit::Millisecond, "MS", Some((Unit::Microsecond, 1000))),
|
||||
(Unit::Second, "SEC", Some((Unit::Millisecond, 1000))),
|
||||
(Unit::Minute, "MIN", Some((Unit::Second, 60))),
|
||||
(Unit::Hour, "HR", Some((Unit::Minute, 60))),
|
||||
(Unit::Day, "DAY", Some((Unit::Minute, 1440))),
|
||||
(Unit::Week, "WK", Some((Unit::Day, 7))),
|
||||
(Unit::Nanosecond, "ns", None),
|
||||
(Unit::Microsecond, "us", Some((Unit::Nanosecond, 1000))),
|
||||
(
|
||||
// µ Micro Sign
|
||||
Unit::Microsecond,
|
||||
"\u{00B5}s",
|
||||
Some((Unit::Nanosecond, 1000)),
|
||||
),
|
||||
(
|
||||
// μ Greek small letter Mu
|
||||
Unit::Microsecond,
|
||||
"\u{03BC}s",
|
||||
Some((Unit::Nanosecond, 1000)),
|
||||
),
|
||||
(Unit::Millisecond, "ms", Some((Unit::Microsecond, 1000))),
|
||||
(Unit::Second, "sec", Some((Unit::Millisecond, 1000))),
|
||||
(Unit::Minute, "min", Some((Unit::Second, 60))),
|
||||
(Unit::Hour, "hr", Some((Unit::Minute, 60))),
|
||||
(Unit::Day, "day", Some((Unit::Minute, 1440))),
|
||||
(Unit::Week, "wk", Some((Unit::Day, 7))),
|
||||
];
|
||||
|
||||
if let Some(unit) = unit_groups
|
||||
.iter()
|
||||
.find(|&x| uppercase_num_with_unit.ends_with(x.1))
|
||||
{
|
||||
if let Some(unit) = unit_groups.iter().find(|&x| num_with_unit.ends_with(x.1)) {
|
||||
let mut lhs = num_with_unit;
|
||||
for _ in 0..unit.1.len() {
|
||||
for _ in 0..unit.1.chars().count() {
|
||||
lhs.pop();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user