for ints, provide an option to convert all of them to filesizes with the into value command (#11797)

# Description

This PR allows `into value` to recognize ints and change them into file
sizes if you prefer.
### Before
```nushell
❯ free | ^column -t | lines | update 0 {$"type  ($in)"} | to text | ^column -t | detect columns | into value 
╭─#─┬─type──┬──total───┬──used───┬───free───┬shared┬buff/cache┬available─╮
│ 0 │ Mem:  │ 24614036 │ 3367680 │ 16196240 │ 3688 │  5449736 │ 21246356 │
│ 1 │ Swap: │  6291456 │       0 │  6291456 │      │          │          │
╰───┴───────┴──────────┴─────────┴──────────┴──────┴──────────┴──────────╯
```
### After
```nushell
❯ free | ^column -t | lines | update 0 {$"type  ($in)"} | to text | ^column -t | detect columns | into value --prefer-filesizes
╭─#─┬─type──┬──total──┬──used──┬──free───┬─shared─┬buff/cache┬available╮
│ 0 │ Mem:  │ 24.6 MB │ 3.4 MB │ 16.2 MB │ 3.7 KB │   5.4 MB │ 21.2 MB │
│ 1 │ Swap: │  6.3 MB │    0 B │  6.3 MB │        │          │         │
╰───┴───────┴─────────┴────────┴─────────┴────────┴──────────┴─────────╯
```
# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# 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` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **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.
-->
This commit is contained in:
Darren Schroeder 2024-02-07 16:28:17 -06:00 committed by GitHub
parent 08931e976e
commit c79432f33c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -27,6 +27,11 @@ impl Command for IntoValue {
"list of columns to update",
Some('c'),
)
.switch(
"prefer-filesizes",
"For ints display them as human-readable file sizes",
Some('f'),
)
.allow_variants_without_examples(true)
.category(Category::Filters)
}
@ -61,6 +66,7 @@ impl Command for IntoValue {
let metadata = input.metadata();
let ctrlc = engine_state.ctrlc.clone();
let span = call.head;
let display_as_filesizes = call.has_flag(&engine_state, stack, "prefer-filesizes")?;
// the columns to update
let columns: Option<Value> = call.get_flag(&engine_state, stack, "columns")?;
@ -79,6 +85,7 @@ impl Command for IntoValue {
Ok(UpdateCellIterator {
input: input.into_iter(),
columns,
display_as_filesizes,
span,
}
.into_pipeline_data(ctrlc)
@ -89,6 +96,7 @@ impl Command for IntoValue {
struct UpdateCellIterator {
input: PipelineIterator,
columns: Option<HashSet<String>>,
display_as_filesizes: bool,
span: Span,
}
@ -112,7 +120,7 @@ impl Iterator for UpdateCellIterator {
Some(cols) if !cols.contains(&col) => (col, val),
_ => (
col,
match process_cell(val, span) {
match process_cell(val, self.display_as_filesizes, span) {
Ok(val) => val,
Err(err) => Value::error(err, span),
},
@ -121,7 +129,7 @@ impl Iterator for UpdateCellIterator {
.collect(),
span,
)),
val => match process_cell(val, self.span) {
val => match process_cell(val, self.display_as_filesizes, self.span) {
Ok(val) => Some(val),
Err(err) => Some(Value::error(err, self.span)),
},
@ -134,7 +142,7 @@ impl Iterator for UpdateCellIterator {
// This function will check each cell to see if it matches a regular expression
// for a particular datatype. If it does, it will convert the cell to that datatype.
fn process_cell(val: Value, span: Span) -> Result<Value, ShellError> {
fn process_cell(val: Value, display_as_filesizes: bool, span: Span) -> Result<Value, ShellError> {
// step 1: convert value to string
let val_str = val.as_string().unwrap_or_default();
@ -177,7 +185,11 @@ fn process_cell(val: Value, span: Span) -> Result<Value, ShellError> {
)),
})?;
Ok(Value::int(ival, span))
if display_as_filesizes {
Ok(Value::filesize(ival, span))
} else {
Ok(Value::int(ival, span))
}
} else if INTEGER_WITH_DELIMS_RE.is_match(&val_str) {
let mut val_str = val_str;
val_str.retain(|x| !['_', ','].contains(&x));
@ -193,7 +205,11 @@ fn process_cell(val: Value, span: Span) -> Result<Value, ShellError> {
)),
})?;
Ok(Value::int(ival, span))
if display_as_filesizes {
Ok(Value::filesize(ival, span))
} else {
Ok(Value::int(ival, span))
}
} else if DATETIME_DMY_RE.is_match(&val_str) {
let dt = parse_date_from_string(&val_str, span).map_err(|_| ShellError::CantConvert {
to_type: "date".to_string(),