From 6cdfee3573720a14db7fb04a4a05ff8a4efd9d4f Mon Sep 17 00:00:00 2001 From: JT <547158+jntrnr@users.noreply.github.com> Date: Mon, 4 Sep 2023 02:27:29 +1200 Subject: [PATCH] Move Value to helpers, separate span call (#10121) # Description As part of the refactor to split spans off of Value, this moves to using helper functions to create values, and using `.span()` instead of matching span out of Value directly. Hoping to get a few more helping hands to finish this, as there are a lot of commands to update :) # User-Facing Changes # Tests + Formatting # After Submitting --------- Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com> Co-authored-by: WindSoilder --- benches/benchmarks.rs | 5 +- crates/nu-cli/src/commands/commandline.rs | 14 +- crates/nu-cli/src/commands/history.rs | 53 +- crates/nu-cli/src/commands/keybindings.rs | 8 +- .../src/commands/keybindings_default.rs | 6 +- .../nu-cli/src/commands/keybindings_list.rs | 6 +- crates/nu-cli/src/completions/completer.rs | 10 +- .../src/completions/variable_completions.rs | 21 +- crates/nu-cli/src/nu_highlight.rs | 10 +- crates/nu-cli/src/reedline_config.rs | 97 +- crates/nu-cli/src/repl.rs | 32 +- crates/nu-cli/src/util.rs | 5 +- .../tests/support/completions_helpers.rs | 49 +- crates/nu-cmd-base/src/hook.rs | 149 +- crates/nu-cmd-base/src/input_handler.rs | 5 +- .../src/dataframe/eager/columns.rs | 13 +- .../src/dataframe/eager/dtypes.rs | 5 +- .../src/dataframe/eager/list.rs | 5 +- .../src/dataframe/eager/query_df.rs | 5 +- .../src/dataframe/eager/summary.rs | 36 +- .../src/dataframe/eager/to_arrow.rs | 10 +- .../src/dataframe/eager/to_avro.rs | 10 +- .../src/dataframe/eager/to_csv.rs | 10 +- .../src/dataframe/eager/to_json_lines.rs | 10 +- .../src/dataframe/eager/to_nu.rs | 15 +- .../src/dataframe/eager/to_parquet.rs | 10 +- .../src/dataframe/eager/with_column.rs | 10 +- .../src/dataframe/lazy/aggregate.rs | 5 +- .../src/dataframe/lazy/collect.rs | 5 +- .../src/dataframe/lazy/fill_nan.rs | 23 +- .../src/dataframe/lazy/groupby.rs | 5 +- .../src/dataframe/lazy/select.rs | 5 +- .../src/dataframe/lazy/sort_by_expr.rs | 5 +- .../src/dataframe/lazy/to_lazy.rs | 5 +- .../src/dataframe/series/date/as_datetime.rs | 32 +- .../dataframe/series/indexes/set_with_idx.rs | 9 +- .../src/dataframe/series/masks/set.rs | 10 +- .../values/nu_dataframe/between_values.rs | 48 +- .../values/nu_dataframe/conversion.rs | 159 +- .../values/nu_dataframe/custom_value.rs | 7 +- .../src/dataframe/values/nu_dataframe/mod.rs | 41 +- .../values/nu_dataframe/operations.rs | 16 +- .../values/nu_expression/custom_value.rs | 16 +- .../src/dataframe/values/nu_expression/mod.rs | 25 +- .../values/nu_lazyframe/custom_value.rs | 5 +- .../src/dataframe/values/nu_lazyframe/mod.rs | 13 +- .../values/nu_lazygroupby/custom_value.rs | 5 +- .../dataframe/values/nu_lazygroupby/mod.rs | 34 +- .../dataframe/values/nu_when/custom_value.rs | 9 +- .../src/dataframe/values/nu_when/mod.rs | 8 +- .../src/dataframe/values/utils.rs | 50 +- crates/nu-cmd-extra/src/extra/bits/and.rs | 24 +- crates/nu-cmd-extra/src/extra/bits/bits_.rs | 8 +- crates/nu-cmd-extra/src/extra/bits/into.rs | 104 +- crates/nu-cmd-extra/src/extra/bits/not.rs | 41 +- crates/nu-cmd-extra/src/extra/bits/or.rs | 24 +- .../src/extra/bits/rotate_left.rs | 31 +- .../src/extra/bits/rotate_right.rs | 31 +- .../nu-cmd-extra/src/extra/bits/shift_left.rs | 39 +- .../src/extra/bits/shift_right.rs | 39 +- crates/nu-cmd-extra/src/extra/bits/xor.rs | 24 +- .../nu-cmd-extra/src/extra/conversions/fmt.rs | 8 +- .../src/extra/filters/each_while.rs | 18 +- .../src/extra/filters/roll/mod.rs | 16 +- .../src/extra/filters/roll/roll_.rs | 8 +- .../src/extra/filters/roll/roll_down.rs | 8 +- .../src/extra/filters/roll/roll_left.rs | 16 +- .../src/extra/filters/roll/roll_right.rs | 16 +- .../src/extra/filters/roll/roll_up.rs | 8 +- .../nu-cmd-extra/src/extra/filters/rotate.rs | 69 +- .../src/extra/filters/update_cells.rs | 24 +- .../nu-cmd-extra/src/extra/formats/to/html.rs | 17 +- crates/nu-cmd-extra/src/extra/math/arccos.rs | 25 +- crates/nu-cmd-extra/src/extra/math/arccosh.rs | 25 +- crates/nu-cmd-extra/src/extra/math/arcsin.rs | 25 +- crates/nu-cmd-extra/src/extra/math/arcsinh.rs | 17 +- crates/nu-cmd-extra/src/extra/math/arctan.rs | 17 +- crates/nu-cmd-extra/src/extra/math/arctanh.rs | 27 +- crates/nu-cmd-extra/src/extra/math/cos.rs | 28 +- crates/nu-cmd-extra/src/extra/math/cosh.rs | 21 +- crates/nu-cmd-extra/src/extra/math/exp.rs | 20 +- crates/nu-cmd-extra/src/extra/math/ln.rs | 25 +- crates/nu-cmd-extra/src/extra/math/sin.rs | 28 +- crates/nu-cmd-extra/src/extra/math/sinh.rs | 20 +- crates/nu-cmd-extra/src/extra/math/tan.rs | 28 +- crates/nu-cmd-extra/src/extra/math/tanh.rs | 20 +- .../src/extra/platform/ansi/gradient.rs | 29 +- .../src/extra/platform/ansi/link.rs | 20 +- .../src/extra/strings/encode_decode/hex.rs | 48 +- .../src/extra/strings/format/command.rs | 8 +- .../src/extra/strings/str_/case/camel_case.rs | 8 +- .../src/extra/strings/str_/case/kebab_case.rs | 8 +- .../src/extra/strings/str_/case/mod.rs | 15 +- .../extra/strings/str_/case/pascal_case.rs | 8 +- .../strings/str_/case/screaming_snake_case.rs | 8 +- .../src/extra/strings/str_/case/snake_case.rs | 8 +- .../src/extra/strings/str_/case/str_.rs | 8 +- .../src/extra/strings/str_/case/title_case.rs | 8 +- .../nu-cmd-lang/src/core_commands/describe.rs | 6 +- crates/nu-cmd-lang/src/core_commands/do_.rs | 5 +- crates/nu-cmd-lang/src/core_commands/echo.rs | 8 +- .../src/core_commands/error_make.rs | 25 +- .../nu-cmd-lang/src/core_commands/export.rs | 8 +- .../src/core_commands/lazy_make.rs | 18 +- .../src/core_commands/overlay/command.rs | 8 +- .../src/core_commands/overlay/list.rs | 6 +- .../src/core_commands/scope/command.rs | 8 +- crates/nu-color-config/src/color_config.rs | 25 +- crates/nu-color-config/src/style_computer.rs | 88 +- crates/nu-command/src/bytes/add.rs | 48 +- crates/nu-command/src/bytes/at.rs | 98 +- crates/nu-command/src/bytes/build_.rs | 14 +- crates/nu-command/src/bytes/bytes_.rs | 8 +- crates/nu-command/src/bytes/collect.rs | 31 +- crates/nu-command/src/bytes/ends_with.rs | 14 +- crates/nu-command/src/bytes/index_of.rs | 71 +- crates/nu-command/src/bytes/length.rs | 22 +- crates/nu-command/src/bytes/remove.rs | 66 +- crates/nu-command/src/bytes/replace.rs | 67 +- crates/nu-command/src/bytes/reverse.rs | 32 +- crates/nu-command/src/bytes/starts_with.rs | 22 +- .../nu-command/src/charting/hashable_value.rs | 128 +- crates/nu-command/src/charting/histogram.rs | 28 +- crates/nu-command/src/conversions/fill.rs | 44 +- .../nu-command/src/conversions/into/binary.rs | 102 +- .../nu-command/src/conversions/into/bool.rs | 31 +- .../src/conversions/into/command.rs | 8 +- .../src/conversions/into/datetime.rs | 199 ++- .../src/conversions/into/decimal.rs | 43 +- .../src/conversions/into/duration.rs | 73 +- .../src/conversions/into/filesize.rs | 81 +- crates/nu-command/src/conversions/into/int.rs | 169 +-- .../nu-command/src/conversions/into/record.rs | 65 +- .../nu-command/src/conversions/into/string.rs | 83 +- .../src/database/commands/into_sqlite.rs | 14 +- .../nu-command/src/database/values/sqlite.rs | 66 +- crates/nu-command/src/date/date_.rs | 8 +- crates/nu-command/src/date/humanize.rs | 33 +- crates/nu-command/src/date/list_timezone.rs | 8 +- crates/nu-command/src/date/now.rs | 6 +- crates/nu-command/src/date/to_record.rs | 56 +- crates/nu-command/src/date/to_table.rs | 65 +- crates/nu-command/src/date/to_timezone.rs | 35 +- crates/nu-command/src/date/utils.rs | 17 +- crates/nu-command/src/debug/ast.rs | 16 +- crates/nu-command/src/debug/debug_.rs | 26 +- crates/nu-command/src/debug/explain.rs | 5 +- crates/nu-command/src/debug/inspect_table.rs | 8 +- crates/nu-command/src/debug/timeit.rs | 5 +- crates/nu-command/src/debug/view.rs | 8 +- crates/nu-command/src/debug/view_files.rs | 6 +- crates/nu-command/src/env/config/config_.rs | 8 +- crates/nu-command/src/env/export_env.rs | 4 +- crates/nu-command/src/filesystem/cd.rs | 5 +- crates/nu-command/src/filesystem/cp.rs | 45 +- crates/nu-command/src/filesystem/glob.rs | 29 +- crates/nu-command/src/filesystem/ls.rs | 12 +- crates/nu-command/src/filesystem/mkdir.rs | 2 +- crates/nu-command/src/filesystem/mv.rs | 7 +- crates/nu-command/src/filesystem/rm.rs | 25 +- crates/nu-command/src/filesystem/watch.rs | 2 +- crates/nu-command/src/filters/append.rs | 43 +- crates/nu-command/src/filters/columns.rs | 116 +- crates/nu-command/src/filters/compact.rs | 21 +- crates/nu-command/src/filters/default.rs | 48 +- crates/nu-command/src/filters/drop/column.rs | 76 +- crates/nu-command/src/filters/drop/drop_.rs | 32 +- crates/nu-command/src/filters/drop/nth.rs | 55 +- crates/nu-command/src/filters/each.rs | 62 +- crates/nu-command/src/filters/enumerate.rs | 8 +- crates/nu-command/src/filters/every.rs | 16 +- crates/nu-command/src/filters/filter.rs | 68 +- crates/nu-command/src/filters/find.rs | 226 +-- crates/nu-command/src/filters/first.rs | 108 +- crates/nu-command/src/filters/flatten.rs | 85 +- crates/nu-command/src/filters/get.rs | 8 +- crates/nu-command/src/filters/group.rs | 26 +- crates/nu-command/src/filters/group_by.rs | 71 +- crates/nu-command/src/filters/headers.rs | 38 +- crates/nu-command/src/filters/insert.rs | 33 +- crates/nu-command/src/filters/items.rs | 13 +- crates/nu-command/src/filters/join.rs | 25 +- crates/nu-command/src/filters/last.rs | 94 +- crates/nu-command/src/filters/length.rs | 3 +- crates/nu-command/src/filters/lines.rs | 34 +- crates/nu-command/src/filters/merge.rs | 26 +- crates/nu-command/src/filters/move_.rs | 26 +- crates/nu-command/src/filters/par_each.rs | 66 +- crates/nu-command/src/filters/prepend.rs | 43 +- crates/nu-command/src/filters/range.rs | 34 +- crates/nu-command/src/filters/reject.rs | 8 +- crates/nu-command/src/filters/rename.rs | 204 ++- crates/nu-command/src/filters/reverse.rs | 16 +- crates/nu-command/src/filters/select.rs | 112 +- crates/nu-command/src/filters/skip/skip_.rs | 62 +- .../nu-command/src/filters/skip/skip_until.rs | 24 +- .../nu-command/src/filters/skip/skip_while.rs | 24 +- crates/nu-command/src/filters/sort.rs | 83 +- crates/nu-command/src/filters/sort_by.rs | 8 +- crates/nu-command/src/filters/split_by.rs | 58 +- crates/nu-command/src/filters/take/take_.rs | 86 +- .../nu-command/src/filters/take/take_until.rs | 24 +- .../nu-command/src/filters/take/take_while.rs | 24 +- crates/nu-command/src/filters/transpose.rs | 44 +- crates/nu-command/src/filters/uniq.rs | 76 +- crates/nu-command/src/filters/uniq_by.rs | 55 +- crates/nu-command/src/filters/update.rs | 46 +- crates/nu-command/src/filters/upsert.rs | 47 +- crates/nu-command/src/filters/utils.rs | 12 +- crates/nu-command/src/filters/values.rs | 99 +- crates/nu-command/src/filters/where_.rs | 21 +- crates/nu-command/src/filters/window.rs | 93 +- crates/nu-command/src/filters/wrap.rs | 16 +- crates/nu-command/src/filters/zip.rs | 61 +- crates/nu-command/src/formats/from/command.rs | 8 +- crates/nu-command/src/formats/from/csv.rs | 8 +- .../nu-command/src/formats/from/delimited.rs | 27 +- crates/nu-command/src/formats/from/json.rs | 41 +- crates/nu-command/src/formats/from/nuon.rs | 143 +- crates/nu-command/src/formats/from/ods.rs | 8 +- crates/nu-command/src/formats/from/ssv.rs | 18 +- crates/nu-command/src/formats/from/toml.rs | 26 +- crates/nu-command/src/formats/from/tsv.rs | 8 +- crates/nu-command/src/formats/from/xlsx.rs | 8 +- crates/nu-command/src/formats/from/xml.rs | 5 +- crates/nu-command/src/formats/from/yaml.rs | 68 +- crates/nu-command/src/formats/to/command.rs | 8 +- crates/nu-command/src/formats/to/delimited.rs | 5 +- crates/nu-command/src/formats/to/json.rs | 19 +- crates/nu-command/src/formats/to/md.rs | 25 +- crates/nu-command/src/formats/to/nuon.rs | 14 +- crates/nu-command/src/formats/to/text.rs | 6 +- crates/nu-command/src/formats/to/toml.rs | 36 +- crates/nu-command/src/formats/to/xml.rs | 20 +- crates/nu-command/src/formats/to/yaml.rs | 16 +- crates/nu-command/src/generators/cal.rs | 13 +- crates/nu-command/src/generators/seq.rs | 16 +- crates/nu-command/src/generators/seq_char.rs | 12 +- crates/nu-command/src/generators/seq_date.rs | 21 +- crates/nu-command/src/hash/generic_digest.rs | 43 +- crates/nu-command/src/hash/hash_.rs | 8 +- crates/nu-command/src/hash/md5.rs | 42 +- crates/nu-command/src/hash/sha256.rs | 43 +- crates/nu-command/src/help/help_.rs | 14 +- crates/nu-command/src/help/help_aliases.rs | 6 +- crates/nu-command/src/help/help_commands.rs | 13 +- crates/nu-command/src/help/help_externs.rs | 9 +- crates/nu-command/src/help/help_modules.rs | 6 +- crates/nu-command/src/math/abs.rs | 31 +- crates/nu-command/src/math/avg.rs | 11 +- crates/nu-command/src/math/ceil.rs | 24 +- crates/nu-command/src/math/floor.rs | 24 +- crates/nu-command/src/math/log.rs | 33 +- crates/nu-command/src/math/math_.rs | 8 +- crates/nu-command/src/math/mode.rs | 36 +- crates/nu-command/src/math/reducers.rs | 29 +- crates/nu-command/src/math/round.rs | 57 +- crates/nu-command/src/math/sqrt.rs | 35 +- crates/nu-command/src/math/stddev.rs | 18 +- crates/nu-command/src/math/utils.rs | 6 +- crates/nu-command/src/network/http/http_.rs | 8 +- .../nu-command/src/network/url/build_query.rs | 67 +- crates/nu-command/src/network/url/encode.rs | 38 +- crates/nu-command/src/network/url/join.rs | 40 +- crates/nu-command/src/network/url/url_.rs | 8 +- crates/nu-command/src/path/exists.rs | 11 +- crates/nu-command/src/path/expand.rs | 8 +- crates/nu-command/src/path/join.rs | 36 +- crates/nu-command/src/path/mod.rs | 8 +- crates/nu-command/src/path/path_.rs | 8 +- crates/nu-command/src/path/relative_to.rs | 8 +- crates/nu-command/src/path/split.rs | 39 +- crates/nu-command/src/platform/ansi/ansi_.rs | 2 +- crates/nu-command/src/platform/ansi/strip.rs | 15 +- crates/nu-command/src/platform/clear.rs | 2 +- crates/nu-command/src/platform/dir_info.rs | 5 +- crates/nu-command/src/platform/du.rs | 5 +- .../nu-command/src/platform/input/input_.rs | 6 +- .../src/platform/input/input_listen.rs | 3 +- crates/nu-command/src/platform/input/list.rs | 18 +- crates/nu-command/src/platform/kill.rs | 11 +- crates/nu-command/src/platform/sleep.rs | 6 +- crates/nu-command/src/random/bool.rs | 8 +- crates/nu-command/src/random/chars.rs | 5 +- crates/nu-command/src/random/decimal.rs | 10 +- crates/nu-command/src/random/dice.rs | 5 +- crates/nu-command/src/random/integer.rs | 4 +- crates/nu-command/src/random/random_.rs | 8 +- crates/nu-command/src/random/uuid.rs | 5 +- crates/nu-command/src/sort_utils.rs | 104 +- .../nu-command/src/strings/detect_columns.rs | 16 +- .../src/strings/encode_decode/base64.rs | 78 +- .../src/strings/encode_decode/decode.rs | 43 +- .../src/strings/encode_decode/encode.rs | 43 +- .../src/strings/encode_decode/encoding.rs | 10 +- crates/nu-command/src/strings/format/date.rs | 62 +- .../nu-command/src/strings/format/duration.rs | 31 +- .../nu-command/src/strings/format/filesize.rs | 19 +- crates/nu-command/src/strings/parse.rs | 75 +- crates/nu-command/src/strings/size.rs | 21 +- crates/nu-command/src/strings/split/chars.rs | 40 +- crates/nu-command/src/strings/split/column.rs | 45 +- .../nu-command/src/strings/split/command.rs | 8 +- crates/nu-command/src/strings/split/list.rs | 129 +- crates/nu-command/src/strings/split/row.rs | 50 +- crates/nu-command/src/strings/split/words.rs | 37 +- .../src/strings/str_/case/capitalize.rs | 28 +- .../src/strings/str_/case/downcase.rs | 36 +- .../nu-command/src/strings/str_/case/mod.rs | 15 +- .../nu-command/src/strings/str_/case/str_.rs | 8 +- .../src/strings/str_/case/upcase.rs | 20 +- .../nu-command/src/strings/str_/contains.rs | 42 +- .../nu-command/src/strings/str_/distance.rs | 18 +- .../nu-command/src/strings/str_/ends_with.rs | 10 +- crates/nu-command/src/strings/str_/expand.rs | 190 ++- .../nu-command/src/strings/str_/index_of.rs | 78 +- crates/nu-command/src/strings/str_/join.rs | 6 +- crates/nu-command/src/strings/str_/length.rs | 23 +- crates/nu-command/src/strings/str_/replace.rs | 54 +- crates/nu-command/src/strings/str_/reverse.rs | 23 +- .../src/strings/str_/starts_with.rs | 10 +- .../nu-command/src/strings/str_/substring.rs | 33 +- .../nu-command/src/strings/str_/trim/trim_.rs | 111 +- crates/nu-command/src/system/complete.rs | 10 +- crates/nu-command/src/system/nu_check.rs | 3 +- crates/nu-command/src/system/run_external.rs | 8 +- crates/nu-command/src/system/sys.rs | 23 +- crates/nu-command/src/viewers/griddle.rs | 5 +- crates/nu-command/src/viewers/table.rs | 55 +- crates/nu-engine/src/documentation.rs | 2 +- crates/nu-engine/src/env.rs | 127 +- crates/nu-engine/src/eval.rs | 114 +- crates/nu-engine/src/scope.rs | 22 +- crates/nu-explore/src/commands/config.rs | 5 +- crates/nu-explore/src/commands/help.rs | 30 +- crates/nu-explore/src/explore.rs | 5 +- crates/nu-explore/src/nu_common/table.rs | 7 +- crates/nu-explore/src/nu_common/value.rs | 24 +- crates/nu-explore/src/views/record/mod.rs | 5 +- crates/nu-parser/src/eval.rs | 115 ++ crates/nu-plugin/src/plugin/declaration.rs | 11 +- crates/nu-plugin/src/plugin/mod.rs | 33 +- .../nu-plugin/src/protocol/evaluated_call.rs | 37 +- .../src/protocol/plugin_custom_value.rs | 5 +- crates/nu-plugin/src/serializers/json.rs | 25 +- crates/nu-plugin/src/serializers/msgpack.rs | 25 +- crates/nu-protocol/src/config.rs | 82 +- .../nu-protocol/src/engine/pattern_match.rs | 8 +- crates/nu-protocol/src/eval_const.rs | 37 +- crates/nu-protocol/src/pipeline_data.rs | 224 ++- crates/nu-protocol/src/value/from_value.rs | 136 +- crates/nu-protocol/src/value/mod.rs | 1276 ++++++++--------- crates/nu-protocol/src/value/range.rs | 19 +- crates/nu-protocol/src/value/stream.rs | 30 +- crates/nu-protocol/src/value/unit.rs | 91 +- .../nu-protocol/tests/test_pipeline_data.rs | 13 +- crates/nu-protocol/tests/test_value.rs | 4 +- crates/nu-table/src/types/expanded.rs | 18 +- .../src/cool_custom_value.rs | 23 +- .../src/second_custom_value.rs | 23 +- crates/nu_plugin_example/src/example.rs | 7 +- crates/nu_plugin_formats/src/from/eml.rs | 47 +- crates/nu_plugin_formats/src/from/ics.rs | 113 +- crates/nu_plugin_formats/src/from/vcf.rs | 60 +- crates/nu_plugin_gstat/src/nu/mod.rs | 2 +- crates/nu_plugin_inc/src/inc.rs | 2 +- crates/nu_plugin_inc/src/nu/mod.rs | 2 +- crates/nu_plugin_query/src/query_json.rs | 2 +- crates/nu_plugin_query/src/query_web.rs | 16 +- crates/nu_plugin_query/src/query_xml.rs | 21 +- src/command.rs | 8 +- src/main.rs | 7 +- 372 files changed, 5811 insertions(+), 7448 deletions(-) create mode 100644 crates/nu-parser/src/eval.rs diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 7729c000e..128049ed5 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -120,10 +120,7 @@ fn encoding_test_data(row_cnt: usize, col_cnt: usize) -> Value { .collect(), ); - Value::List { - vals: vec![record; row_cnt], - span: Span::test_data(), - } + Value::list(vec![record; row_cnt], Span::test_data()) } fn encoding_benchmarks(c: &mut Criterion) { diff --git a/crates/nu-cli/src/commands/commandline.rs b/crates/nu-cli/src/commands/commandline.rs index 646b5cd12..17b02fa6c 100644 --- a/crates/nu-cli/src/commands/commandline.rs +++ b/crates/nu-cli/src/commands/commandline.rs @@ -102,7 +102,7 @@ impl Command for Commandline { repl.buffer = cmd.as_string()?; repl.cursor_pos = repl.buffer.len(); } - Ok(Value::Nothing { span: call.head }.into_pipeline_data()) + Ok(Value::nothing(call.head).into_pipeline_data()) } else { let repl = engine_state.repl_state.lock().expect("repl state mutex"); if call.has_flag("cursor") { @@ -112,17 +112,9 @@ impl Command for Commandline { .chain(std::iter::once((repl.buffer.len(), ""))) .position(|(i, _c)| i == repl.cursor_pos) .expect("Cursor position isn't on a grapheme boundary"); - Ok(Value::String { - val: char_pos.to_string(), - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(char_pos.to_string(), call.head).into_pipeline_data()) } else { - Ok(Value::String { - val: repl.buffer.to_string(), - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(repl.buffer.to_string(), call.head).into_pipeline_data()) } } } diff --git a/crates/nu-cli/src/commands/history.rs b/crates/nu-cli/src/commands/history.rs index 0ecea17ed..3a0de5e8a 100644 --- a/crates/nu-cli/src/commands/history.rs +++ b/crates/nu-cli/src/commands/history.rs @@ -151,8 +151,8 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span) //1. Format all the values //2. Create a record of either short or long columns and values - let item_id_value = Value::Int { - val: match entry.id { + let item_id_value = Value::int( + match entry.id { Some(id) => { let ids = id.to_string(); match ids.parse::() { @@ -162,21 +162,18 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span) } None => 0i64, }, - span: head, - }; - let start_timestamp_value = Value::String { - val: match entry.start_timestamp { + head, + ); + let start_timestamp_value = Value::string( + match entry.start_timestamp { Some(time) => time.to_string(), None => "".into(), }, - span: head, - }; - let command_value = Value::String { - val: entry.command_line, - span: head, - }; - let session_id_value = Value::Int { - val: match entry.session_id { + head, + ); + let command_value = Value::string(entry.command_line, head); + let session_id_value = Value::int( + match entry.session_id { Some(sid) => { let sids = sid.to_string(); match sids.parse::() { @@ -186,29 +183,29 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span) } None => 0i64, }, - span: head, - }; - let hostname_value = Value::String { - val: match entry.hostname { + head, + ); + let hostname_value = Value::string( + match entry.hostname { Some(host) => host, None => "".into(), }, - span: head, - }; - let cwd_value = Value::String { - val: match entry.cwd { + head, + ); + let cwd_value = Value::string( + match entry.cwd { Some(cwd) => cwd, None => "".into(), }, - span: head, - }; - let duration_value = Value::Duration { - val: match entry.duration { + head, + ); + let duration_value = Value::duration( + match entry.duration { Some(d) => d.as_nanos().try_into().unwrap_or(0), None => 0, }, - span: head, - }; + head, + ); let exit_status_value = Value::int(entry.exit_status.unwrap_or(0), head); let index_value = Value::int(idx as i64, head); if long { diff --git a/crates/nu-cli/src/commands/keybindings.rs b/crates/nu-cli/src/commands/keybindings.rs index 5ed1bfa2e..9c1bd0820 100644 --- a/crates/nu-cli/src/commands/keybindings.rs +++ b/crates/nu-cli/src/commands/keybindings.rs @@ -41,16 +41,16 @@ For more information on input and keybindings, check: call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Keybindings.signature(), &Keybindings.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-cli/src/commands/keybindings_default.rs b/crates/nu-cli/src/commands/keybindings_default.rs index 8670150f0..c853dd749 100644 --- a/crates/nu-cli/src/commands/keybindings_default.rs +++ b/crates/nu-cli/src/commands/keybindings_default.rs @@ -53,10 +53,6 @@ impl Command for KeybindingsDefault { }) .collect(); - Ok(Value::List { - vals: records, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::list(records, call.head).into_pipeline_data()) } } diff --git a/crates/nu-cli/src/commands/keybindings_list.rs b/crates/nu-cli/src/commands/keybindings_list.rs index efa2d12bb..0ae2286cf 100644 --- a/crates/nu-cli/src/commands/keybindings_list.rs +++ b/crates/nu-cli/src/commands/keybindings_list.rs @@ -71,11 +71,7 @@ impl Command for KeybindingsList { .collect() }; - Ok(Value::List { - vals: records, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::list(records, call.head).into_pipeline_data()) } } diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index 13a2410ba..00e3ce613 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -74,13 +74,13 @@ impl NuCompleter { if let Some(var_id) = pos_arg.var_id { callee_stack.add_var( var_id, - Value::List { - vals: spans + Value::list( + spans .iter() .map(|it| Value::string(it, Span::unknown())) .collect(), - span: Span::unknown(), - }, + Span::unknown(), + ), ); } } @@ -97,7 +97,7 @@ impl NuCompleter { match result { Ok(pd) => { let value = pd.into_value(span); - if let Value::List { vals, span: _ } = value { + if let Value::List { vals, .. } = value { let result = map_value_completions(vals.iter(), Span::new(span.start, span.end), offset); diff --git a/crates/nu-cli/src/completions/variable_completions.rs b/crates/nu-cli/src/completions/variable_completions.rs index 2072f9ceb..650d87fc6 100644 --- a/crates/nu-cli/src/completions/variable_completions.rs +++ b/crates/nu-cli/src/completions/variable_completions.rs @@ -263,7 +263,7 @@ fn nested_suggestions( output } - Value::List { vals, span: _ } => { + Value::List { vals, .. } => { for column_name in get_columns(vals.as_slice()) { output.push(Suggestion { value: column_name, @@ -284,6 +284,7 @@ fn nested_suggestions( fn recursive_value(val: Value, sublevels: Vec>) -> Value { // Go to next sublevel if let Some(next_sublevel) = sublevels.clone().into_iter().next() { + let span = val.span(); match val { Value::Record { val, .. } => { for item in val { @@ -295,11 +296,9 @@ fn recursive_value(val: Value, sublevels: Vec>) -> Value { } // Current sublevel value not found - return Value::Nothing { - span: Span::unknown(), - }; + return Value::nothing(span); } - Value::LazyRecord { val, span: _ } => { + Value::LazyRecord { val, .. } => { for col in val.column_names() { if col.as_bytes().to_vec() == next_sublevel { return recursive_value( @@ -310,15 +309,13 @@ fn recursive_value(val: Value, sublevels: Vec>) -> Value { } // Current sublevel value not found - return Value::Nothing { - span: Span::unknown(), - }; + return Value::nothing(span); } - Value::List { vals, span } => { + Value::List { vals, .. } => { for col in get_columns(vals.as_slice()) { if col.as_bytes().to_vec() == next_sublevel { return recursive_value( - Value::List { vals, span } + Value::list(vals, span) .get_data_by_key(&col) .unwrap_or_default(), sublevels.into_iter().skip(1).collect(), @@ -327,9 +324,7 @@ fn recursive_value(val: Value, sublevels: Vec>) -> Value { } // Current sublevel value not found - return Value::Nothing { - span: Span::unknown(), - }; + return Value::nothing(span); } _ => return val, } diff --git a/crates/nu-cli/src/nu_highlight.rs b/crates/nu-cli/src/nu_highlight.rs index a8557ba0a..89b7f8850 100644 --- a/crates/nu-cli/src/nu_highlight.rs +++ b/crates/nu-cli/src/nu_highlight.rs @@ -48,15 +48,9 @@ impl Command for NuHighlight { Ok(line) => { let highlights = highlighter.highlight(&line, line.len()); - Value::String { - val: highlights.render_simple(), - span: head, - } + Value::string(highlights.render_simple(), head) } - Err(err) => Value::Error { - error: Box::new(err), - span: head, - }, + Err(err) => Value::error(err, head), }, ctrlc, ) diff --git a/crates/nu-cli/src/reedline_config.rs b/crates/nu-cli/src/reedline_config.rs index 7916e99e8..2453734d4 100644 --- a/crates/nu-cli/src/reedline_config.rs +++ b/crates/nu-cli/src/reedline_config.rs @@ -131,8 +131,9 @@ fn add_menu( stack: &Stack, config: &Config, ) -> Result { - if let Value::Record { val, span } = &menu.menu_type { - let layout = extract_value("layout", val, *span)?.into_string("", config); + let span = menu.menu_type.span(); + if let Value::Record { val, .. } = &menu.menu_type { + let layout = extract_value("layout", val, span)?.into_string("", config); match layout.as_str() { "columnar" => add_columnar_menu(line_editor, menu, engine_state, stack, config), @@ -156,7 +157,7 @@ fn add_menu( macro_rules! add_style { // first arm match add!(1,2), add!(2,3) etc ($name:expr, $record: expr, $span:expr, $config: expr, $menu:expr, $f:expr) => { - $menu = match extract_value($name, $record, *$span) { + $menu = match extract_value($name, $record, $span) { Ok(text) => { let style = match text { Value::String { val, .. } => lookup_ansi_color_style(&val), @@ -178,11 +179,12 @@ pub(crate) fn add_columnar_menu( stack: &Stack, config: &Config, ) -> Result { + let span = menu.menu_type.span(); let name = menu.name.into_string("", config); let mut columnar_menu = ColumnarMenu::default().with_name(&name); - if let Value::Record { val, span } = &menu.menu_type { - columnar_menu = match extract_value("columns", val, *span) { + if let Value::Record { val, .. } = &menu.menu_type { + columnar_menu = match extract_value("columns", val, span) { Ok(columns) => { let columns = columns.as_int()?; columnar_menu.with_columns(columns as u16) @@ -190,7 +192,7 @@ pub(crate) fn add_columnar_menu( Err(_) => columnar_menu, }; - columnar_menu = match extract_value("col_width", val, *span) { + columnar_menu = match extract_value("col_width", val, span) { Ok(col_width) => { let col_width = col_width.as_int()?; columnar_menu.with_column_width(Some(col_width as usize)) @@ -198,7 +200,7 @@ pub(crate) fn add_columnar_menu( Err(_) => columnar_menu.with_column_width(None), }; - columnar_menu = match extract_value("col_padding", val, *span) { + columnar_menu = match extract_value("col_padding", val, span) { Ok(col_padding) => { let col_padding = col_padding.as_int()?; columnar_menu.with_column_padding(col_padding as usize) @@ -207,7 +209,8 @@ pub(crate) fn add_columnar_menu( }; } - if let Value::Record { val, span } = &menu.style { + let span = menu.style.span(); + if let Value::Record { val, .. } = &menu.style { add_style!( "text", val, @@ -240,18 +243,15 @@ pub(crate) fn add_columnar_menu( let only_buffer_difference = menu.only_buffer_difference.as_bool()?; columnar_menu = columnar_menu.with_only_buffer_difference(only_buffer_difference); + let span = menu.source.span(); match &menu.source { Value::Nothing { .. } => { Ok(line_editor.with_menu(ReedlineMenu::EngineCompleter(Box::new(columnar_menu)))) } - Value::Closure { - val, - captures, - span, - } => { + Value::Closure { val, captures, .. } => { let menu_completer = NuMenuCompleter::new( *val, - *span, + span, stack.captures_to_stack(captures), engine_state, only_buffer_difference, @@ -264,7 +264,7 @@ pub(crate) fn add_columnar_menu( _ => Err(ShellError::UnsupportedConfigValue( "block or omitted value".to_string(), menu.source.into_abbreviated_string(config), - menu.source.span(), + span, )), } } @@ -280,8 +280,9 @@ pub(crate) fn add_list_menu( let name = menu.name.into_string("", config); let mut list_menu = ListMenu::default().with_name(&name); - if let Value::Record { val, span } = &menu.menu_type { - list_menu = match extract_value("page_size", val, *span) { + let span = menu.menu_type.span(); + if let Value::Record { val, .. } = &menu.menu_type { + list_menu = match extract_value("page_size", val, span) { Ok(page_size) => { let page_size = page_size.as_int()?; list_menu.with_page_size(page_size as usize) @@ -290,7 +291,8 @@ pub(crate) fn add_list_menu( }; } - if let Value::Record { val, span } = &menu.style { + let span = menu.style.span(); + if let Value::Record { val, .. } = &menu.style { add_style!( "text", val, @@ -323,18 +325,15 @@ pub(crate) fn add_list_menu( let only_buffer_difference = menu.only_buffer_difference.as_bool()?; list_menu = list_menu.with_only_buffer_difference(only_buffer_difference); + let span = menu.source.span(); match &menu.source { Value::Nothing { .. } => { Ok(line_editor.with_menu(ReedlineMenu::HistoryMenu(Box::new(list_menu)))) } - Value::Closure { - val, - captures, - span, - } => { + Value::Closure { val, captures, .. } => { let menu_completer = NuMenuCompleter::new( *val, - *span, + span, stack.captures_to_stack(captures), engine_state, only_buffer_difference, @@ -363,8 +362,9 @@ pub(crate) fn add_description_menu( let name = menu.name.into_string("", config); let mut description_menu = DescriptionMenu::default().with_name(&name); - if let Value::Record { val, span } = &menu.menu_type { - description_menu = match extract_value("columns", val, *span) { + let span = menu.menu_type.span(); + if let Value::Record { val, .. } = &menu.menu_type { + description_menu = match extract_value("columns", val, span) { Ok(columns) => { let columns = columns.as_int()?; description_menu.with_columns(columns as u16) @@ -372,7 +372,7 @@ pub(crate) fn add_description_menu( Err(_) => description_menu, }; - description_menu = match extract_value("col_width", val, *span) { + description_menu = match extract_value("col_width", val, span) { Ok(col_width) => { let col_width = col_width.as_int()?; description_menu.with_column_width(Some(col_width as usize)) @@ -380,7 +380,7 @@ pub(crate) fn add_description_menu( Err(_) => description_menu.with_column_width(None), }; - description_menu = match extract_value("col_padding", val, *span) { + description_menu = match extract_value("col_padding", val, span) { Ok(col_padding) => { let col_padding = col_padding.as_int()?; description_menu.with_column_padding(col_padding as usize) @@ -388,7 +388,7 @@ pub(crate) fn add_description_menu( Err(_) => description_menu, }; - description_menu = match extract_value("selection_rows", val, *span) { + description_menu = match extract_value("selection_rows", val, span) { Ok(selection_rows) => { let selection_rows = selection_rows.as_int()?; description_menu.with_selection_rows(selection_rows as u16) @@ -396,7 +396,7 @@ pub(crate) fn add_description_menu( Err(_) => description_menu, }; - description_menu = match extract_value("description_rows", val, *span) { + description_menu = match extract_value("description_rows", val, span) { Ok(description_rows) => { let description_rows = description_rows.as_int()?; description_menu.with_description_rows(description_rows as usize) @@ -405,7 +405,8 @@ pub(crate) fn add_description_menu( }; } - if let Value::Record { val, span } = &menu.style { + let span = menu.style.span(); + if let Value::Record { val, .. } = &menu.style { add_style!( "text", val, @@ -438,6 +439,7 @@ pub(crate) fn add_description_menu( let only_buffer_difference = menu.only_buffer_difference.as_bool()?; description_menu = description_menu.with_only_buffer_difference(only_buffer_difference); + let span = menu.source.span(); match &menu.source { Value::Nothing { .. } => { let completer = Box::new(NuHelpCompleter::new(engine_state)); @@ -446,14 +448,10 @@ pub(crate) fn add_description_menu( completer, })) } - Value::Closure { - val, - captures, - span, - } => { + Value::Closure { val, captures, .. } => { let menu_completer = NuMenuCompleter::new( *val, - *span, + span, stack.captures_to_stack(captures), engine_state, only_buffer_difference, @@ -575,15 +573,16 @@ fn add_keybinding( insert_keybindings: &mut Keybindings, normal_keybindings: &mut Keybindings, ) -> Result<(), ShellError> { + let span = mode.span(); match &mode { - Value::String { val, span } => match val.as_str() { + Value::String { val, .. } => match val.as_str() { "emacs" => add_parsed_keybinding(emacs_keybindings, keybinding, config), "vi_insert" => add_parsed_keybinding(insert_keybindings, keybinding, config), "vi_normal" => add_parsed_keybinding(normal_keybindings, keybinding, config), m => Err(ShellError::UnsupportedConfigValue( "emacs, vi_insert or vi_normal".to_string(), m.to_string(), - *span, + span, )), }, Value::List { vals, .. } => { @@ -724,13 +723,14 @@ impl<'config> EventType<'config> { } fn parse_event(value: &Value, config: &Config) -> Result, ShellError> { + let span = value.span(); match value { - Value::Record { val: record, span } => match EventType::try_from_record(record, *span)? { + Value::Record { val: record, .. } => match EventType::try_from_record(record, span)? { EventType::Send(value) => event_from_record( value.into_string("", config).to_lowercase().as_str(), record, config, - *span, + span, ) .map(Some), EventType::Edit(value) => { @@ -738,7 +738,7 @@ fn parse_event(value: &Value, config: &Config) -> Result, value.into_string("", config).to_lowercase().as_str(), record, config, - *span, + span, )?; Ok(Some(ReedlineEvent::Edit(vec![edit]))) } @@ -1056,10 +1056,10 @@ mod test { // Until event let cols = vec!["until".to_string()]; - let vals = vec![Value::List { - vals: vec![menu_event, enter_event], - span: Span::test_data(), - }]; + let vals = vec![Value::list( + vec![menu_event, enter_event], + Span::test_data(), + )]; let event = Record { cols, vals }; let span = Span::test_data(); @@ -1097,10 +1097,7 @@ mod test { let enter_event = Value::test_record(Record { cols, vals }); // Multiple event - let event = Value::List { - vals: vec![menu_event, enter_event], - span: Span::test_data(), - }; + let event = Value::list(vec![menu_event, enter_event], Span::test_data()); let config = Config::default(); let parsed_event = parse_event(&event, &config).unwrap(); diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index e77218f63..415778448 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -514,24 +514,12 @@ pub fn evaluate_repl( (path.to_string_lossy().to_string(), tokens.0[0].span) }; - stack.add_env_var( - "OLDPWD".into(), - Value::String { - val: cwd.clone(), - span: Span::unknown(), - }, - ); + stack.add_env_var("OLDPWD".into(), Value::string(cwd.clone(), Span::unknown())); //FIXME: this only changes the current scope, but instead this environment variable //should probably be a block that loads the information from the state in the overlay - stack.add_env_var( - "PWD".into(), - Value::String { - val: path.clone(), - span: Span::unknown(), - }, - ); - let cwd = Value::String { val: cwd, span }; + stack.add_env_var("PWD".into(), Value::string(path.clone(), Span::unknown())); + let cwd = Value::string(cwd, span); let shells = stack.get_env_var(engine_state, "NUSHELL_SHELLS"); let mut shells = if let Some(v) = shells { @@ -556,15 +544,12 @@ pub fn evaluate_repl( 0 }; - shells[current_shell] = Value::String { val: path, span }; + shells[current_shell] = Value::string(path, span); - stack.add_env_var("NUSHELL_SHELLS".into(), Value::List { vals: shells, span }); + stack.add_env_var("NUSHELL_SHELLS".into(), Value::list(shells, span)); stack.add_env_var( "NUSHELL_LAST_SHELL".into(), - Value::Int { - val: last_shell as i64, - span, - }, + Value::int(last_shell as i64, span), ); } else if !s.trim().is_empty() { trace!("eval source: {}", s); @@ -607,10 +592,7 @@ pub fn evaluate_repl( stack.add_env_var( "CMD_DURATION_MS".into(), - Value::String { - val: format!("{}", cmd_duration.as_millis()), - span: Span::unknown(), - }, + Value::string(format!("{}", cmd_duration.as_millis()), Span::unknown()), ); if history_supports_meta && !s.is_empty() && line_editor.has_last_command_context() diff --git a/crates/nu-cli/src/util.rs b/crates/nu-cli/src/util.rs index 5dc76b485..e28367d4c 100644 --- a/crates/nu-cli/src/util.rs +++ b/crates/nu-cli/src/util.rs @@ -185,10 +185,7 @@ fn gather_env_vars( continue; } - Value::String { - val: bytes, - span: *span, - } + Value::string(bytes, *span) } else { report_capture_error( engine_state, diff --git a/crates/nu-cli/tests/support/completions_helpers.rs b/crates/nu-cli/tests/support/completions_helpers.rs index d1bc9056e..8d1432313 100644 --- a/crates/nu-cli/tests/support/completions_helpers.rs +++ b/crates/nu-cli/tests/support/completions_helpers.rs @@ -40,33 +40,30 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { // Add pwd as env var stack.add_env_var( "PWD".to_string(), - Value::String { - val: dir_str.clone(), - span: nu_protocol::Span::new(0, dir_str.len()), - }, + Value::string(dir_str.clone(), nu_protocol::Span::new(0, dir_str.len())), ); stack.add_env_var( "TEST".to_string(), - Value::String { - val: "NUSHELL".to_string(), - span: nu_protocol::Span::new(0, dir_str.len()), - }, + Value::string( + "NUSHELL".to_string(), + nu_protocol::Span::new(0, dir_str.len()), + ), ); #[cfg(windows)] stack.add_env_var( "Path".to_string(), - Value::String { - val: "c:\\some\\path;c:\\some\\other\\path".to_string(), - span: nu_protocol::Span::new(0, dir_str.len()), - }, + Value::string( + "c:\\some\\path;c:\\some\\other\\path".to_string(), + nu_protocol::Span::new(0, dir_str.len()), + ), ); #[cfg(not(windows))] stack.add_env_var( "PATH".to_string(), - Value::String { - val: "/some/path:/some/other/path".to_string(), - span: nu_protocol::Span::new(0, dir_str.len()), - }, + Value::string( + "/some/path:/some/other/path".to_string(), + nu_protocol::Span::new(0, dir_str.len()), + ), ); // Merge environment into the permanent state @@ -95,17 +92,14 @@ pub fn new_quote_engine() -> (PathBuf, String, EngineState, Stack) { // Add pwd as env var stack.add_env_var( "PWD".to_string(), - Value::String { - val: dir_str.clone(), - span: nu_protocol::Span::new(0, dir_str.len()), - }, + Value::string(dir_str.clone(), nu_protocol::Span::new(0, dir_str.len())), ); stack.add_env_var( "TEST".to_string(), - Value::String { - val: "NUSHELL".to_string(), - span: nu_protocol::Span::new(0, dir_str.len()), - }, + Value::string( + "NUSHELL".to_string(), + nu_protocol::Span::new(0, dir_str.len()), + ), ); // Merge environment into the permanent state @@ -168,12 +162,7 @@ pub fn merge_input( engine_state, stack, &block, - PipelineData::Value( - Value::Nothing { - span: Span::unknown(), - }, - None - ), + PipelineData::Value(Value::nothing(Span::unknown(),), None), false, false ) diff --git a/crates/nu-cmd-base/src/hook.rs b/crates/nu-cmd-base/src/hook.rs index 800877107..fa79a1a2e 100644 --- a/crates/nu-cmd-base/src/hook.rs +++ b/crates/nu-cmd-base/src/hook.rs @@ -84,8 +84,9 @@ pub fn eval_hook( optional: false, }; + let span = value.span(); match value { - Value::String { val, span } => { + Value::String { val, .. } => { let (block, delta, vars) = { let mut working_set = StateWorkingSet::new(engine_state); @@ -113,7 +114,7 @@ pub fn eval_hook( return Err(ShellError::UnsupportedConfigValue( "valid source code".into(), "source code with syntax errors".into(), - *span, + span, )); } @@ -161,64 +162,56 @@ pub fn eval_hook( } } Value::Record { .. } => { - let do_run_hook = - if let Ok(condition) = value.clone().follow_cell_path(&[condition_path], false) { - match condition { - Value::Block { - val: block_id, - span: block_span, - .. - } - | Value::Closure { - val: block_id, - span: block_span, - .. - } => { - match run_hook_block( - engine_state, - stack, - block_id, - None, - arguments.clone(), - block_span, - ) { - Ok(pipeline_data) => { - if let PipelineData::Value(Value::Bool { val, .. }, ..) = - pipeline_data - { - val - } else { - return Err(ShellError::UnsupportedConfigValue( - "boolean output".to_string(), - "other PipelineData variant".to_string(), - block_span, - )); - } - } - Err(err) => { - return Err(err); + let do_run_hook = if let Ok(condition) = + value.clone().follow_cell_path(&[condition_path], false) + { + let other_span = condition.span(); + match condition { + Value::Block { val: block_id, .. } | Value::Closure { val: block_id, .. } => { + match run_hook_block( + engine_state, + stack, + block_id, + None, + arguments.clone(), + other_span, + ) { + Ok(pipeline_data) => { + if let PipelineData::Value(Value::Bool { val, .. }, ..) = + pipeline_data + { + val + } else { + return Err(ShellError::UnsupportedConfigValue( + "boolean output".to_string(), + "other PipelineData variant".to_string(), + other_span, + )); } } - } - other => { - return Err(ShellError::UnsupportedConfigValue( - "block".to_string(), - format!("{}", other.get_type()), - other.span(), - )); + Err(err) => { + return Err(err); + } } } - } else { - // always run the hook - true - }; + other => { + return Err(ShellError::UnsupportedConfigValue( + "block".to_string(), + format!("{}", other.get_type()), + other_span, + )); + } + } + } else { + // always run the hook + true + }; if do_run_hook { - match value.clone().follow_cell_path(&[code_path], false)? { - Value::String { - val, - span: source_span, - } => { + let follow = value.clone().follow_cell_path(&[code_path], false)?; + let source_span = follow.span(); + match follow { + Value::String { val, .. } => { let (block, delta, vars) = { let mut working_set = StateWorkingSet::new(engine_state); @@ -277,71 +270,41 @@ pub fn eval_hook( stack.remove_var(*var_id); } } - Value::Block { - val: block_id, - span: block_span, - .. - } => { + Value::Block { val: block_id, .. } => { run_hook_block( engine_state, stack, block_id, input, arguments, - block_span, + source_span, )?; } - Value::Closure { - val: block_id, - span: block_span, - .. - } => { + Value::Closure { val: block_id, .. } => { run_hook_block( engine_state, stack, block_id, input, arguments, - block_span, + source_span, )?; } other => { return Err(ShellError::UnsupportedConfigValue( "block or string".to_string(), format!("{}", other.get_type()), - other.span(), + source_span, )); } } } } - Value::Block { - val: block_id, - span: block_span, - .. - } => { - output = run_hook_block( - engine_state, - stack, - *block_id, - input, - arguments, - *block_span, - )?; + Value::Block { val: block_id, .. } => { + output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?; } - Value::Closure { - val: block_id, - span: block_span, - .. - } => { - output = run_hook_block( - engine_state, - stack, - *block_id, - input, - arguments, - *block_span, - )?; + Value::Closure { val: block_id, .. } => { + output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?; } other => { return Err(ShellError::UnsupportedConfigValue( diff --git a/crates/nu-cmd-base/src/input_handler.rs b/crates/nu-cmd-base/src/input_handler.rs index 70e063f41..978782285 100644 --- a/crates/nu-cmd-base/src/input_handler.rs +++ b/crates/nu-cmd-base/src/input_handler.rs @@ -76,10 +76,7 @@ where }), ); if let Err(error) = r { - return Value::Error { - error: Box::new(error), - span, - }; + return Value::error(error, span); } } v diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/columns.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/columns.rs index 0a7dccfb9..b071ce2ba 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/columns.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/columns.rs @@ -27,10 +27,10 @@ impl Command for ColumnsDF { vec![Example { description: "Dataframe columns", example: "[[a b]; [1 2] [3 4]] | dfr into-df | dfr columns", - result: Some(Value::List { - vals: vec![Value::test_string("a"), Value::test_string("b")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("a"), Value::test_string("b")], + Span::test_data(), + )), }] } @@ -60,10 +60,7 @@ fn command( .map(|v| Value::string(*v, call.head)) .collect(); - let names = Value::List { - vals: names, - span: call.head, - }; + let names = Value::list(names, call.head); Ok(PipelineData::Value(names, None)) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/dtypes.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/dtypes.rs index c7e2a8299..275c4c87c 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/dtypes.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/dtypes.rs @@ -79,10 +79,7 @@ fn command( .dtype(); let dtype_str = dtype.to_string(); - dtypes.push(Value::String { - val: dtype_str, - span: call.head, - }); + dtypes.push(Value::string(dtype_str, call.head)); Value::string(*v, call.head) }) diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/list.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/list.rs index 78b5f3a5d..0fe412ffe 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/list.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/list.rs @@ -66,10 +66,7 @@ impl Command for ListDF { }) .collect::>(); - let list = Value::List { - vals, - span: call.head, - }; + let list = Value::list(vals, call.head); Ok(list.into_pipeline_data()) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/query_df.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/query_df.rs index 1d76e0ae1..5775184b3 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/query_df.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/query_df.rs @@ -88,10 +88,7 @@ fn command( let lazy = NuLazyFrame::new(false, df_sql); let eager = lazy.collect(call.head)?; - let value = Value::CustomValue { - val: Box::new(eager), - span: call.head, - }; + let value = Value::custom_value(Box::new(eager), call.head); Ok(PipelineData::Value(value, None)) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/summary.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/summary.rs index f92cb0a0b..8792643c4 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/summary.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/summary.rs @@ -120,30 +120,30 @@ fn command( let quantiles = quantiles.map(|values| { values .iter() - .map(|value| match value { - Value::Float { val, span } => { - if (&0.0..=&1.0).contains(&val) { - Ok(*val) - } else { - Err(ShellError::GenericError( - "Incorrect value for quantile".to_string(), - "value should be between 0 and 1".to_string(), - Some(*span), - None, - Vec::new(), - )) + .map(|value| { + let span = value.span(); + match value { + Value::Float { val, .. } => { + if (&0.0..=&1.0).contains(&val) { + Ok(*val) + } else { + Err(ShellError::GenericError( + "Incorrect value for quantile".to_string(), + "value should be between 0 and 1".to_string(), + Some(span), + None, + Vec::new(), + )) + } } - } - Value::Error { error, .. } => Err(*error.clone()), - _ => { - let span = value.span(); - Err(ShellError::GenericError( + Value::Error { error, .. } => Err(*error.clone()), + _ => Err(ShellError::GenericError( "Incorrect value for quantile".to_string(), "value should be a float".to_string(), Some(span), None, Vec::new(), - )) + )), } }) .collect::, ShellError>>() diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_arrow.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_arrow.rs index b4b484804..8cef0f801 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_arrow.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_arrow.rs @@ -78,16 +78,10 @@ fn command( ) })?; - let file_value = Value::String { - val: format!("saved {:?}", &file_name.item), - span: file_name.span, - }; + let file_value = Value::string(format!("saved {:?}", &file_name.item), file_name.span); Ok(PipelineData::Value( - Value::List { - vals: vec![file_value], - span: call.head, - }, + Value::list(vec![file_value], call.head), None, )) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_avro.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_avro.rs index ad442d073..6dc3a138a 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_avro.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_avro.rs @@ -108,16 +108,10 @@ fn command( ) })?; - let file_value = Value::String { - val: format!("saved {:?}", &file_name.item), - span: file_name.span, - }; + let file_value = Value::string(format!("saved {:?}", &file_name.item), file_name.span); Ok(PipelineData::Value( - Value::List { - vals: vec![file_value], - span: call.head, - }, + Value::list(vec![file_value], call.head), None, )) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs index 26d36f119..0f416b6f7 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_csv.rs @@ -124,16 +124,10 @@ fn command( ) })?; - let file_value = Value::String { - val: format!("saved {:?}", &file_name.item), - span: file_name.span, - }; + let file_value = Value::string(format!("saved {:?}", &file_name.item), file_name.span); Ok(PipelineData::Value( - Value::List { - vals: vec![file_value], - span: call.head, - }, + Value::list(vec![file_value], call.head), None, )) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_json_lines.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_json_lines.rs index 976af7e58..a10122734 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_json_lines.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_json_lines.rs @@ -81,16 +81,10 @@ fn command( ) })?; - let file_value = Value::String { - val: format!("saved {:?}", &file_name.item), - span: file_name.span, - }; + let file_value = Value::string(format!("saved {:?}", &file_name.item), file_name.span); Ok(PipelineData::Value( - Value::List { - vals: vec![file_value], - span: call.head, - }, + Value::list(vec![file_value], call.head), None, )) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs index 7cb7c6322..f97ba42cd 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_nu.rs @@ -57,18 +57,12 @@ impl Command for ToNu { Example { description: "Shows head rows from dataframe", example: "[[a b]; [1 2] [3 4]] | dfr into-df | dfr into-nu", - result: Some(Value::List { - vals: vec![rec_1, rec_2], - span: Span::test_data(), - }), + result: Some(Value::list(vec![rec_1, rec_2], Span::test_data())), }, Example { description: "Shows tail rows from dataframe", example: "[[a b]; [1 2] [5 6] [3 4]] | dfr into-df | dfr into-nu -t -n 1", - result: Some(Value::List { - vals: vec![rec_3], - span: Span::test_data(), - }), + result: Some(Value::list(vec![rec_3], Span::test_data())), }, Example { description: "Convert a col expression into a nushell value", @@ -119,10 +113,7 @@ fn dataframe_command( } }; - let value = Value::List { - vals: values, - span: call.head, - }; + let value = Value::list(values, call.head); Ok(PipelineData::Value(value, None)) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/to_parquet.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/to_parquet.rs index ab2421fbd..0926b8aa1 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/to_parquet.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/to_parquet.rs @@ -78,16 +78,10 @@ fn command( ) })?; - let file_value = Value::String { - val: format!("saved {:?}", &file_name.item), - span: file_name.span, - }; + let file_value = Value::string(format!("saved {:?}", &file_name.item), file_name.span); Ok(PipelineData::Value( - Value::List { - vals: vec![file_value], - span: call.head, - }, + Value::list(vec![file_value], call.head), None, )) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/eager/with_column.rs b/crates/nu-cmd-dataframe/src/dataframe/eager/with_column.rs index 53e57501e..2b29a0adc 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/eager/with_column.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/eager/with_column.rs @@ -132,10 +132,7 @@ fn command_eager( if NuExpression::can_downcast(&new_column) { let vals: Vec = call.rest(engine_state, stack, 0)?; - let value = Value::List { - vals, - span: call.head, - }; + let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; let lazy = NuLazyFrame::new(true, df.lazy().with_columns(&expressions)); @@ -179,10 +176,7 @@ fn command_lazy( lazy: NuLazyFrame, ) -> Result { let vals: Vec = call.rest(engine_state, stack, 0)?; - let value = Value::List { - vals, - span: call.head, - }; + let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; let lazy: NuLazyFrame = lazy.into_polars().with_columns(&expressions).into(); diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/aggregate.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/aggregate.rs index 972d9d7dd..877e40d70 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/aggregate.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/aggregate.rs @@ -114,10 +114,7 @@ impl Command for LazyAggregate { input: PipelineData, ) -> Result { let vals: Vec = call.rest(engine_state, stack, 0)?; - let value = Value::List { - vals, - span: call.head, - }; + let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; let group_by = NuLazyGroupBy::try_from_pipeline(input, call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/collect.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/collect.rs index 55b13f304..30a635ee2 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/collect.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/collect.rs @@ -58,10 +58,7 @@ impl Command for LazyCollect { ) -> Result { let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?; let eager = lazy.collect(call.head)?; - let value = Value::CustomValue { - val: Box::new(eager), - span: call.head, - }; + let value = Value::custom_value(Box::new(eager), call.head); Ok(PipelineData::Value(value, None)) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/fill_nan.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/fill_nan.rs index bc5f9ec18..10321b0be 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/fill_nan.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/fill_nan.rs @@ -102,18 +102,21 @@ impl Command for LazyFillNA { let column_name = column.name().to_string(); let values = column .into_iter() - .map(|value| match value { - Value::Float { val, .. } => { - if val.is_nan() { - fill.clone() - } else { - value + .map(|value| { + let span = value.span(); + match value { + Value::Float { val, .. } => { + if val.is_nan() { + fill.clone() + } else { + value + } } + Value::List { vals, .. } => { + NuDataFrame::fill_list_nan(vals, span, fill.clone()) + } + _ => value, } - Value::List { vals, span } => { - NuDataFrame::fill_list_nan(vals, span, fill.clone()) - } - _ => value, }) .collect::>(); Column::new(column_name, values) diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/groupby.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/groupby.rs index 9a1a2bb88..048c62130 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/groupby.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/groupby.rs @@ -113,10 +113,7 @@ impl Command for ToLazyGroupBy { input: PipelineData, ) -> Result { let vals: Vec = call.rest(engine_state, stack, 0)?; - let value = Value::List { - vals, - span: call.head, - }; + let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; if expressions diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/select.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/select.rs index 18c9206e3..25809ee11 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/select.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/select.rs @@ -55,10 +55,7 @@ impl Command for LazySelect { input: PipelineData, ) -> Result { let vals: Vec = call.rest(engine_state, stack, 0)?; - let value = Value::List { - vals, - span: call.head, - }; + let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; let lazy = NuLazyFrame::try_from_pipeline(input, call.head)?; diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs index 531a25aa9..c573650d2 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/sort_by_expr.rs @@ -105,10 +105,7 @@ impl Command for LazySortBy { input: PipelineData, ) -> Result { let vals: Vec = call.rest(engine_state, stack, 0)?; - let value = Value::List { - vals, - span: call.head, - }; + let value = Value::list(vals, call.head); let expressions = NuExpression::extract_exprs(value)?; let nulls_last = call.has_flag("nulls-last"); let maintain_order = call.has_flag("maintain-order"); diff --git a/crates/nu-cmd-dataframe/src/dataframe/lazy/to_lazy.rs b/crates/nu-cmd-dataframe/src/dataframe/lazy/to_lazy.rs index cfbcaf32b..168da2d37 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/lazy/to_lazy.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/lazy/to_lazy.rs @@ -41,10 +41,7 @@ impl Command for ToLazyFrame { ) -> Result { let df = NuDataFrame::try_from_iter(input.into_iter())?; let lazy = NuLazyFrame::from_dataframe(df); - let value = Value::CustomValue { - val: Box::new(lazy), - span: call.head, - }; + let value = Value::custom_value(Box::new(lazy), call.head); Ok(PipelineData::Value(value, None)) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs b/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs index 0b04f7849..8a31b1c83 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/date/as_datetime.rs @@ -56,22 +56,22 @@ impl Command for AsDateTime { NuDataFrame::try_from_columns(vec![Column::new( "datetime".to_string(), vec![ - Value::Date { - val: DateTime::parse_from_str( + Value::date( + DateTime::parse_from_str( "2021-12-30 00:00:00 +0000", "%Y-%m-%d %H:%M:%S %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, - Value::Date { - val: DateTime::parse_from_str( + Span::test_data(), + ), + Value::date( + DateTime::parse_from_str( "2021-12-31 00:00:00 +0000", "%Y-%m-%d %H:%M:%S %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, + Span::test_data(), + ), ], )]) .expect("simple df for test should not fail") @@ -85,22 +85,22 @@ impl Command for AsDateTime { NuDataFrame::try_from_columns(vec![Column::new( "datetime".to_string(), vec![ - Value::Date { - val: DateTime::parse_from_str( + Value::date( + DateTime::parse_from_str( "2021-12-30 00:00:00.123456789 +0000", "%Y-%m-%d %H:%M:%S.%9f %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, - Value::Date { - val: DateTime::parse_from_str( + Span::test_data(), + ), + Value::date( + DateTime::parse_from_str( "2021-12-31 00:00:00.123456789 +0000", "%Y-%m-%d %H:%M:%S.%9f %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, + Span::test_data(), + ), ], )]) .expect("simple df for test should not fail") diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/indexes/set_with_idx.rs b/crates/nu-cmd-dataframe/src/dataframe/series/indexes/set_with_idx.rs index 8731996b5..33b3d8795 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/indexes/set_with_idx.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/indexes/set_with_idx.rs @@ -123,8 +123,9 @@ fn command( let df = NuDataFrame::try_from_pipeline(input, call.head)?; let series = df.as_series(call.head)?; + let span = value.span(); let res = match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { let chunked = series.i64().map_err(|e| { ShellError::GenericError( "Error casting to i64".into(), @@ -147,7 +148,7 @@ fn command( NuDataFrame::try_from_series(vec![res.into_series()], call.head) } - Value::Float { val, span } => { + Value::Float { val, .. } => { let chunked = series.f64().map_err(|e| { ShellError::GenericError( "Error casting to f64".into(), @@ -170,7 +171,7 @@ fn command( NuDataFrame::try_from_series(vec![res.into_series()], call.head) } - Value::String { val, span } => { + Value::String { val, .. } => { let chunked = series.utf8().map_err(|e| { ShellError::GenericError( "Error casting to string".into(), @@ -204,7 +205,7 @@ fn command( "this value cannot be set in a series of type '{}'", series.dtype() ), - Some(value.span()), + Some(span), None, Vec::new(), )), diff --git a/crates/nu-cmd-dataframe/src/dataframe/series/masks/set.rs b/crates/nu-cmd-dataframe/src/dataframe/series/masks/set.rs index d94866722..930a3f813 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/series/masks/set.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/series/masks/set.rs @@ -105,9 +105,9 @@ fn command( let df = NuDataFrame::try_from_pipeline(input, call.head)?; let series = df.as_series(call.head)?; - + let span = value.span(); let res = match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { let chunked = series.i64().map_err(|e| { ShellError::GenericError( "Error casting to i64".into(), @@ -130,7 +130,7 @@ fn command( NuDataFrame::try_from_series(vec![res.into_series()], call.head) } - Value::Float { val, span } => { + Value::Float { val, .. } => { let chunked = series.f64().map_err(|e| { ShellError::GenericError( "Error casting to f64".into(), @@ -153,7 +153,7 @@ fn command( NuDataFrame::try_from_series(vec![res.into_series()], call.head) } - Value::String { val, span } => { + Value::String { val, .. } => { let chunked = series.utf8().map_err(|e| { ShellError::GenericError( "Error casting to string".into(), @@ -185,7 +185,7 @@ fn command( "this value cannot be set in a series of type '{}'", series.dtype() ), - Some(value.span()), + Some(span), None, Vec::new(), )), diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/between_values.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/between_values.rs index fccd9c81d..63fa850cc 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/between_values.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/between_values.rs @@ -267,29 +267,37 @@ pub(super) fn compute_series_single_value( rhs_span: right.span(), }), }, - Operator::Math(Math::Divide) => match &right { - Value::Int { val, span } => { - if *val == 0 { - Err(ShellError::DivisionByZero { span: *span }) - } else { - compute_series_i64(&lhs, *val, >::div, lhs_span) + Operator::Math(Math::Divide) => { + let span = right.span(); + match &right { + Value::Int { val, .. } => { + if *val == 0 { + Err(ShellError::DivisionByZero { span }) + } else { + compute_series_i64(&lhs, *val, >::div, lhs_span) + } } - } - Value::Float { val, span } => { - if val.is_zero() { - Err(ShellError::DivisionByZero { span: *span }) - } else { - compute_series_decimal(&lhs, *val, >::div, lhs_span) + Value::Float { val, .. } => { + if val.is_zero() { + Err(ShellError::DivisionByZero { span }) + } else { + compute_series_decimal( + &lhs, + *val, + >::div, + lhs_span, + ) + } } + _ => Err(ShellError::OperatorMismatch { + op_span: operator.span, + lhs_ty: left.get_type().to_string(), + lhs_span: left.span(), + rhs_ty: right.get_type().to_string(), + rhs_span: right.span(), + }), } - _ => Err(ShellError::OperatorMismatch { - op_span: operator.span, - lhs_ty: left.get_type().to_string(), - lhs_span: left.span(), - rhs_ty: right.get_type().to_string(), - rhs_span: right.span(), - }), - }, + } Operator::Comparison(Comparison::Equal) => match &right { Value::Int { val, .. } => compare_series_i64(&lhs, *val, ChunkedArray::equal, lhs_span), Value::Float { val, .. } => { diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/conversion.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/conversion.rs index 93e444f0c..d4d110ea3 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/conversion.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/conversion.rs @@ -452,7 +452,7 @@ fn series_to_values( ) -> Result, ShellError> { match series.dtype() { DataType::Null => { - let it = std::iter::repeat(Value::Nothing { span }); + let it = std::iter::repeat(Value::nothing(span)); let values = if let Some(size) = maybe_size { Either::Left(it.take(size)) } else { @@ -480,11 +480,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -508,11 +505,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -536,11 +530,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -564,11 +555,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -592,11 +580,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -620,11 +605,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -648,11 +630,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { - val: a as i64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::int(a as i64, span), + None => Value::nothing(span), }) .collect::>(); @@ -676,8 +655,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Int { val: a, span }, - None => Value::Nothing { span }, + Some(a) => Value::int(a, span), + None => Value::nothing(span), }) .collect::>(); @@ -701,11 +680,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Float { - val: a as f64, - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::float(a as f64, span), + None => Value::nothing(span), }) .collect::>(); @@ -729,8 +705,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Float { val: a, span }, - None => Value::Nothing { span }, + Some(a) => Value::float(a, span), + None => Value::nothing(span), }) .collect::>(); @@ -754,8 +730,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::Bool { val: a, span }, - None => Value::Nothing { span }, + Some(a) => Value::bool(a, span), + None => Value::nothing(span), }) .collect::>(); @@ -779,11 +755,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(a) => Value::String { - val: a.into(), - span, - }, - None => Value::Nothing { span }, + Some(a) => Value::string(a.to_string(), span), + None => Value::nothing(span), }) .collect::>(); @@ -812,7 +785,7 @@ fn series_to_values( } .map(|v| match v { Some(a) => a.get_value(), - None => Value::Nothing { span }, + None => Value::nothing(span), }) .collect::>(); @@ -850,10 +823,7 @@ fn series_to_values( } }) .unwrap_or(vec![]); - Value::List { - vals: sublist, - span, - } + Value::list(sublist, span) }) .collect::>(); Ok(values) @@ -884,43 +854,40 @@ fn series_to_values( let naive_datetime = match NaiveDateTime::from_timestamp_opt(seconds, 0) { Some(val) => val, None => { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( + return Value::error( + ShellError::UnsupportedInput( "The given local datetime representation is invalid." .to_string(), format!("timestamp is {a:?}"), span, Span::unknown(), - )), + ), span, - } + ) } }; // Zero length offset let offset = match FixedOffset::east_opt(0) { Some(val) => val, None => { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( + return Value::error( + ShellError::UnsupportedInput( "The given local datetime representation is invalid." .to_string(), format!("timestamp is {a:?}"), span, Span::unknown(), - )), + ), span, - } + ) } }; let datetime = DateTime::::from_naive_utc_and_offset(naive_datetime, offset); - Value::Date { - val: datetime, - span, - } + Value::date(datetime, span) } - None => Value::Nothing { span }, + None => Value::nothing(span), }) .collect::>(); @@ -955,43 +922,40 @@ fn series_to_values( let naive_datetime = match NaiveDateTime::from_timestamp_opt(seconds, 0) { Some(val) => val, None => { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( + return Value::error( + ShellError::UnsupportedInput( "The given local datetime representation is invalid." .to_string(), format!("timestamp is {a:?}"), span, Span::unknown(), - )), + ), span, - } + ) } }; // Zero length offset let offset = match FixedOffset::east_opt(0) { Some(val) => val, None => { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( + return Value::error( + ShellError::UnsupportedInput( "The given local datetime representation is invalid." .to_string(), format!("timestamp is {a:?}"), span, Span::unknown(), - )), + ), span, - } + ) } }; let datetime = DateTime::::from_naive_utc_and_offset(naive_datetime, offset); - Value::Date { - val: datetime, - span, - } + Value::date(datetime, span) } - None => Value::Nothing { span }, + None => Value::nothing(span), }) .collect::>(); @@ -1015,11 +979,8 @@ fn series_to_values( Either::Right(it) } .map(|v| match v { - Some(nanoseconds) => Value::Duration { - val: nanoseconds, - span, - }, - None => Value::Nothing { span }, + Some(nanoseconds) => Value::duration(nanoseconds, span), + None => Value::nothing(span), }) .collect::>(); @@ -1043,20 +1004,14 @@ mod tests { #[test] fn test_parsed_column_string_list() -> Result<(), Box> { let values = vec![ - Value::List { - vals: vec![Value::String { - val: "bar".to_string(), - span: Span::test_data(), - }], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::String { - val: "baz".to_string(), - span: Span::test_data(), - }], - span: Span::test_data(), - }, + Value::list( + vec![Value::string("bar".to_string(), Span::test_data())], + Span::test_data(), + ), + Value::list( + vec![Value::string("baz".to_string(), Span::test_data())], + Span::test_data(), + ), ]; let column = Column { name: "foo".to_string(), diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/custom_value.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/custom_value.rs index e657756a5..973dc40e6 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/custom_value.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/custom_value.rs @@ -17,10 +17,7 @@ impl CustomValue for NuDataFrame { from_lazy: false, }; - Value::CustomValue { - val: Box::new(cloned), - span, - } + Value::custom_value(Box::new(cloned), span) } fn value_string(&self) -> String { @@ -30,7 +27,7 @@ impl CustomValue for NuDataFrame { fn to_base_value(&self, span: Span) -> Result { let vals = self.print(span)?; - Ok(Value::List { vals, span }) + Ok(Value::list(vals, span)) } fn as_any(&self) -> &dyn std::any::Any { diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs index c1d54288a..9e09a735c 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/mod.rs @@ -38,9 +38,7 @@ impl Display for DataFrameValue { impl Default for DataFrameValue { fn default() -> Self { - Self(Value::Nothing { - span: Span::unknown(), - }) + Self(Value::nothing(Span::unknown())) } } @@ -111,24 +109,15 @@ impl NuDataFrame { } pub fn dataframe_into_value(dataframe: DataFrame, span: Span) -> Value { - Value::CustomValue { - val: Box::new(Self::new(false, dataframe)), - span, - } + Value::custom_value(Box::new(Self::new(false, dataframe)), span) } pub fn into_value(self, span: Span) -> Value { if self.from_lazy { let lazy = NuLazyFrame::from_dataframe(self); - Value::CustomValue { - val: Box::new(lazy), - span, - } + Value::custom_value(Box::new(lazy), span) } else { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } } @@ -207,16 +196,19 @@ impl NuDataFrame { pub fn fill_list_nan(list: Vec, list_span: Span, fill: Value) -> Value { let newlist = list .into_iter() - .map(|value| match value { - Value::Float { val, .. } => { - if val.is_nan() { - fill.clone() - } else { - value + .map(|value| { + let span = value.span(); + match value { + Value::Float { val, .. } => { + if val.is_nan() { + fill.clone() + } else { + value + } } + Value::List { vals, .. } => Self::fill_list_nan(vals, span, fill.clone()), + _ => value, } - Value::List { vals, span } => Self::fill_list_nan(vals, span, fill.clone()), - _ => value, }) .collect::>(); Value::list(newlist, list_span) @@ -250,8 +242,9 @@ impl NuDataFrame { } pub fn get_df(value: Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { Some(df) => Ok(NuDataFrame { df: df.df.clone(), from_lazy: false, diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/operations.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/operations.rs index 6c3d13baf..4d18eb915 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/operations.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_dataframe/operations.rs @@ -20,15 +20,13 @@ impl NuDataFrame { op_span: Span, right: &Value, ) -> Result { + let rhs_span = right.span(); match right { - Value::CustomValue { - val: rhs, - span: rhs_span, - } => { + Value::CustomValue { val: rhs, .. } => { let rhs = rhs.as_any().downcast_ref::().ok_or_else(|| { ShellError::DowncastNotPossible( "Unable to create dataframe".to_string(), - *rhs_span, + rhs_span, ) })?; @@ -38,7 +36,7 @@ impl NuDataFrame { .as_series(lhs_span) .expect("Already checked that is a series"); let rhs = &rhs - .as_series(*rhs_span) + .as_series(rhs_span) .expect("Already checked that is a series"); if lhs.dtype() != rhs.dtype() { @@ -46,7 +44,7 @@ impl NuDataFrame { left_message: format!("datatype {}", lhs.dtype()), left_span: lhs_span, right_message: format!("datatype {}", lhs.dtype()), - right_span: *rhs_span, + right_span: rhs_span, }); } @@ -55,7 +53,7 @@ impl NuDataFrame { left_message: format!("len {}", lhs.len()), left_span: lhs_span, right_message: format!("len {}", rhs.len()), - right_span: *rhs_span, + right_span: rhs_span, }); } @@ -78,7 +76,7 @@ impl NuDataFrame { left_message: format!("rows {}", self.df.height()), left_span: lhs_span, right_message: format!("rows {}", rhs.df.height()), - right_span: *rhs_span, + right_span: rhs_span, }); } diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/custom_value.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/custom_value.rs index 09ad57a3b..a418ecf4c 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/custom_value.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/custom_value.rs @@ -20,10 +20,7 @@ impl CustomValue for NuExpression { fn clone_value(&self, span: nu_protocol::Span) -> Value { let cloned = NuExpression(self.0.clone()); - Value::CustomValue { - val: Box::new(cloned), - span, - } + Value::custom_value(Box::new(cloned), span) } fn value_string(&self) -> String { @@ -56,16 +53,11 @@ fn compute_with_value( op: Span, right: &Value, ) -> Result { + let rhs_span = right.span(); match right { - Value::CustomValue { - val: rhs, - span: rhs_span, - } => { + Value::CustomValue { val: rhs, .. } => { let rhs = rhs.as_any().downcast_ref::().ok_or_else(|| { - ShellError::DowncastNotPossible( - "Unable to create expression".to_string(), - *rhs_span, - ) + ShellError::DowncastNotPossible("Unable to create expression".to_string(), rhs_span) })?; match rhs.as_ref() { diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/mod.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/mod.rs index e4c2c9590..dc2f7b48a 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/mod.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_expression/mod.rs @@ -55,15 +55,13 @@ impl From for NuExpression { impl NuExpression { pub fn into_value(self, span: Span) -> Value { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } pub fn try_from_value(value: Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { Some(expr) => Ok(NuExpression(expr.0.clone())), None => Err(ShellError::CantConvert { to_type: "lazy expression".into(), @@ -277,13 +275,10 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Result { Expr::DtypeColumn(dtypes) => { let vals = dtypes .iter() - .map(|d| Value::String { - val: format!("{d}"), - span, - }) + .map(|d| Value::string(format!("{d}"), span)) .collect(); - Ok(Value::List { vals, span }) + Ok(Value::list(vals, span)) } Expr::Sort { expr, options } => Ok(Value::record( record! { @@ -318,10 +313,7 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Result { } => { let by: Result, ShellError> = by.iter().map(|b| expr_to_value(b, span)).collect(); - let descending: Vec = descending - .iter() - .map(|r| Value::Bool { val: *r, span }) - .collect(); + let descending: Vec = descending.iter().map(|r| Value::bool(*r, span)).collect(); Ok(Value::record( record! { @@ -354,10 +346,7 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Result { Expr::Exclude(expr, excluded) => { let excluded = excluded .iter() - .map(|e| Value::String { - val: format!("{e:?}"), - span, - }) + .map(|e| Value::string(format!("{e:?}"), span)) .collect(); Ok(Value::record( diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/custom_value.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/custom_value.rs index 65821f7fc..c66f13be2 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/custom_value.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/custom_value.rs @@ -18,10 +18,7 @@ impl CustomValue for NuLazyFrame { schema: self.schema.clone(), }; - Value::CustomValue { - val: Box::new(cloned), - span, - } + Value::custom_value(Box::new(cloned), span) } fn value_string(&self) -> String { diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/mod.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/mod.rs index 60aac358f..a30a278fd 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/mod.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazyframe/mod.rs @@ -90,15 +90,9 @@ impl NuLazyFrame { pub fn into_value(self, span: Span) -> Result { if self.from_eager { let df = self.collect(span)?; - Ok(Value::CustomValue { - val: Box::new(df), - span, - }) + Ok(Value::custom_value(Box::new(df), span)) } else { - Ok(Value::CustomValue { - val: Box::new(self), - span, - }) + Ok(Value::custom_value(Box::new(self), span)) } } @@ -147,8 +141,9 @@ impl NuLazyFrame { } pub fn get_lazy_df(value: Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { Some(expr) => Ok(Self { lazy: expr.lazy.clone(), from_eager: false, diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/custom_value.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/custom_value.rs index a800b1a88..3eacaf81a 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/custom_value.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/custom_value.rs @@ -18,10 +18,7 @@ impl CustomValue for NuLazyGroupBy { from_eager: self.from_eager, }; - Value::CustomValue { - val: Box::new(cloned), - span, - } + Value::custom_value(Box::new(cloned), span) } fn value_string(&self) -> String { diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/mod.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/mod.rs index 103319f5e..88b1bb574 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/mod.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_lazygroupby/mod.rs @@ -74,10 +74,7 @@ impl From for NuLazyGroupBy { impl NuLazyGroupBy { pub fn into_value(self, span: Span) -> Value { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } pub fn into_polars(self) -> LazyGroupBy { @@ -85,22 +82,21 @@ impl NuLazyGroupBy { } pub fn try_from_value(value: Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => { - match val.as_any().downcast_ref::() { - Some(group) => Ok(Self { - group_by: group.group_by.clone(), - schema: group.schema.clone(), - from_eager: group.from_eager, - }), - None => Err(ShellError::CantConvert { - to_type: "lazy groupby".into(), - from_type: "custom value".into(), - span, - help: None, - }), - } - } + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { + Some(group) => Ok(Self { + group_by: group.group_by.clone(), + schema: group.schema.clone(), + from_eager: group.from_eager, + }), + None => Err(ShellError::CantConvert { + to_type: "lazy groupby".into(), + from_type: "custom value".into(), + span, + help: None, + }), + }, x => Err(ShellError::CantConvert { to_type: "lazy groupby".into(), from_type: x.get_type().to_string(), diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/custom_value.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/custom_value.rs index cc389ecfa..918c61976 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/custom_value.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/custom_value.rs @@ -14,10 +14,7 @@ impl CustomValue for NuWhen { fn clone_value(&self, span: nu_protocol::Span) -> Value { let cloned = self.clone(); - Value::CustomValue { - val: Box::new(cloned), - span, - } + Value::custom_value(Box::new(cloned), span) } fn value_string(&self) -> String { @@ -25,12 +22,12 @@ impl CustomValue for NuWhen { } fn to_base_value(&self, span: Span) -> Result { - let val = match self { + let val: String = match self { NuWhen::Then(_) => "whenthen".into(), NuWhen::ChainedThen(_) => "whenthenthen".into(), }; - let value = Value::String { val, span }; + let value = Value::string(val, span); Ok(value) } diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/mod.rs b/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/mod.rs index 72b4e3596..312de124a 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/mod.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/nu_when/mod.rs @@ -51,15 +51,13 @@ impl From for NuWhen { impl NuWhen { pub fn into_value(self, span: Span) -> Value { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } pub fn try_from_value(value: Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { Some(expr) => Ok(expr.clone()), None => Err(ShellError::CantConvert { to_type: "when expression".into(), diff --git a/crates/nu-cmd-dataframe/src/dataframe/values/utils.rs b/crates/nu-cmd-dataframe/src/dataframe/values/utils.rs index 5460ee659..abc191e06 100644 --- a/crates/nu-cmd-dataframe/src/dataframe/values/utils.rs +++ b/crates/nu-cmd-dataframe/src/dataframe/values/utils.rs @@ -25,18 +25,21 @@ pub(crate) fn convert_columns( let res = columns .into_iter() - .map(|value| match value { - Value::String { val, span } => { - col_span = span_join(&[col_span, span]); - Ok(Spanned { item: val, span }) + .map(|value| { + let span = value.span(); + match value { + Value::String { val, .. } => { + col_span = span_join(&[col_span, span]); + Ok(Spanned { item: val, span }) + } + _ => Err(ShellError::GenericError( + "Incorrect column format".into(), + "Only string as column name".into(), + Some(span), + None, + Vec::new(), + )), } - _ => Err(ShellError::GenericError( - "Incorrect column format".into(), - "Only string as column name".into(), - Some(span), - None, - Vec::new(), - )), }) .collect::>, _>>()?; @@ -65,18 +68,21 @@ pub(crate) fn convert_columns_string( let res = columns .into_iter() - .map(|value| match value { - Value::String { val, span } => { - col_span = span_join(&[col_span, span]); - Ok(val) + .map(|value| { + let span = value.span(); + match value { + Value::String { val, .. } => { + col_span = span_join(&[col_span, span]); + Ok(val) + } + _ => Err(ShellError::GenericError( + "Incorrect column format".into(), + "Only string as column name".into(), + Some(span), + None, + Vec::new(), + )), } - _ => Err(ShellError::GenericError( - "Incorrect column format".into(), - "Only string as column name".into(), - Some(span), - None, - Vec::new(), - )), }) .collect::, _>>()?; diff --git a/crates/nu-cmd-extra/src/extra/bits/and.rs b/crates/nu-cmd-extra/src/extra/bits/and.rs index fa6788763..8f1c9b91d 100644 --- a/crates/nu-cmd-extra/src/extra/bits/and.rs +++ b/crates/nu-cmd-extra/src/extra/bits/and.rs @@ -68,32 +68,30 @@ impl Command for BitsAnd { Example { description: "Apply logical and to a list of numbers", example: "[4 3 2] | bits and 2", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(2), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(2), Value::test_int(2)], + Span::test_data(), + )), }, ] } } fn operate(value: Value, target: i64, head: Span) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => Value::Int { - val: val & target, - span, - }, + Value::Int { val, .. } => Value::int(val & target, span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/bits_.rs b/crates/nu-cmd-extra/src/extra/bits/bits_.rs index 75d9acd34..63664f2a1 100644 --- a/crates/nu-cmd-extra/src/extra/bits/bits_.rs +++ b/crates/nu-cmd-extra/src/extra/bits/bits_.rs @@ -34,16 +34,16 @@ impl Command for Bits { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Bits.signature(), &Bits.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-cmd-extra/src/extra/bits/into.rs b/crates/nu-cmd-extra/src/extra/bits/into.rs index 86176fb17..1699a05d2 100644 --- a/crates/nu-cmd-extra/src/extra/bits/into.rs +++ b/crates/nu-cmd-extra/src/extra/bits/into.rs @@ -71,58 +71,51 @@ impl Command for BitsInto { Example { description: "convert a binary value into a string, padded to 8 places with 0s", example: "01b | into bits", - result: Some(Value::String { - val: "00000001".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("00000001", + Span::test_data(), + )), }, Example { description: "convert an int into a string, padded to 8 places with 0s", example: "1 | into bits", - result: Some(Value::String { - val: "00000001".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("00000001", + Span::test_data(), + )), }, Example { description: "convert a filesize value into a string, padded to 8 places with 0s", example: "1b | into bits", - result: Some(Value::String { - val: "00000001".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("00000001", + Span::test_data(), + )), }, Example { description: "convert a duration value into a string, padded to 8 places with 0s", example: "1ns | into bits", - result: Some(Value::String { - val: "00000001".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("00000001", + Span::test_data(), + )), }, Example { description: "convert a boolean value into a string, padded to 8 places with 0s", example: "true | into bits", - result: Some(Value::String { - val: "00000001".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("00000001", + Span::test_data(), + )), }, Example { description: "convert a datetime value into a string, padded to 8 places with 0s", example: "2023-04-17T01:02:03 | into bits", - result: Some(Value::String { - val: "01001101 01101111 01101110 00100000 01000001 01110000 01110010 00100000 00110001 00110111 00100000 00110000 00110001 00111010 00110000 00110010 00111010 00110000 00110011 00100000 00110010 00110000 00110010 00110011".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("01001101 01101111 01101110 00100000 01000001 01110000 01110010 00100000 00110001 00110111 00100000 00110000 00110001 00111010 00110000 00110010 00111010 00110000 00110011 00100000 00110010 00110000 00110010 00110011", + Span::test_data(), + )), }, Example { description: "convert a string into a raw binary string, padded with 0s to 8 places", example: "'nushell.sh' | into bits", - result: Some(Value::String { - val: "01101110 01110101 01110011 01101000 01100101 01101100 01101100 00101110 01110011 01101000".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string("01101110 01110101 01110011 01101000 01100101 01101100 01101100 00101110 01110011 01101000", + Span::test_data(), + )), }, ] } @@ -139,22 +132,16 @@ fn into_bits( let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths); match input { - PipelineData::ExternalStream { stdout: None, .. } => Ok(Value::Binary { - val: vec![], - span: head, + PipelineData::ExternalStream { stdout: None, .. } => { + Ok(Value::binary(vec![], head).into_pipeline_data()) } - .into_pipeline_data()), PipelineData::ExternalStream { stdout: Some(stream), .. } => { // TODO: in the future, we may want this to stream out, converting each to bytes let output = stream.into_bytes()?; - Ok(Value::Binary { - val: output.item, - span: head, - } - .into_pipeline_data()) + Ok(Value::binary(output.item, head).into_pipeline_data()) } _ => { let args = Arguments { cell_paths }; @@ -170,40 +157,28 @@ fn convert_to_smallest_number_type(num: i64, span: Span) -> Value { for ch in bytes { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } else if let Some(v) = num.to_i16() { let bytes = v.to_ne_bytes(); let mut raw_string = "".to_string(); for ch in bytes { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } else if let Some(v) = num.to_i32() { let bytes = v.to_ne_bytes(); let mut raw_string = "".to_string(); for ch in bytes { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } else { let bytes = num.to_ne_bytes(); let mut raw_string = "".to_string(); for ch in bytes { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } } @@ -214,10 +189,7 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value { for ch in val { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } Value::Int { val, .. } => convert_to_smallest_number_type(*val, span), Value::Filesize { val, .. } => convert_to_smallest_number_type(*val, span), @@ -228,10 +200,7 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value { for ch in raw_bytes { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } Value::Bool { val, .. } => { let v = >::from(*val); @@ -244,22 +213,19 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value { for ch in bytes { raw_string.push_str(&format!("{:08b} ", ch)); } - Value::String { - val: raw_string.trim().to_string(), - span, - } + Value::string(raw_string.trim(), span) } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer, filesize, string, date, duration, binary or bool".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/not.rs b/crates/nu-cmd-extra/src/extra/bits/not.rs index e932208c3..f97d9759f 100644 --- a/crates/nu-cmd-extra/src/extra/bits/not.rs +++ b/crates/nu-cmd-extra/src/extra/bits/not.rs @@ -84,50 +84,51 @@ impl Command for BitsNot { Example { description: "Apply logical negation to a list of numbers", example: "[4 3 2] | bits not", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(140737488355323), Value::test_int(140737488355324), Value::test_int(140737488355325), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Apply logical negation to a list of numbers, treat input as 2 bytes number", example: "[4 3 2] | bits not -n '2'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(65531), Value::test_int(65532), Value::test_int(65533), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Apply logical negation to a list of numbers, treat input as signed number", example: "[4 3 2] | bits not -s", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(-5), Value::test_int(-4), Value::test_int(-3), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } } fn operate(value: Value, head: Span, signed: bool, number_size: NumberBytes) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { if signed || val < 0 { - Value::Int { val: !val, span } + Value::int(!val, span) } else { use NumberBytes::*; let out_val = match number_size { @@ -149,21 +150,21 @@ fn operate(value: Value, head: Span, signed: bool, number_size: NumberBytes) -> // This case shouldn't happen here, as it's handled before Invalid => 0, }; - Value::Int { val: out_val, span } + Value::int(out_val, span) } } other => match other { // Propagate errors inside the value Value::Error { .. } => other, - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), }, } } diff --git a/crates/nu-cmd-extra/src/extra/bits/or.rs b/crates/nu-cmd-extra/src/extra/bits/or.rs index cbf0585f1..b89bd8ba6 100644 --- a/crates/nu-cmd-extra/src/extra/bits/or.rs +++ b/crates/nu-cmd-extra/src/extra/bits/or.rs @@ -68,32 +68,30 @@ impl Command for BitsOr { Example { description: "Apply logical or to a list of numbers", example: "[8 3 2] | bits or 2", - result: Some(Value::List { - vals: vec![Value::test_int(10), Value::test_int(3), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(10), Value::test_int(3), Value::test_int(2)], + Span::test_data(), + )), }, ] } } fn operate(value: Value, target: i64, head: Span) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => Value::Int { - val: val | target, - span, - }, + Value::Int { val, .. } => Value::int(val | target, span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs index 89288a39b..d2e54d313 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs @@ -91,10 +91,10 @@ impl Command for BitsRol { Example { description: "Rotate left a list of numbers with 2 bits", example: "[5 3 2] | bits rol 2", - result: Some(Value::List { - vals: vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)], + Span::test_data(), + )), }, ] } @@ -106,9 +106,9 @@ where { let rotate_result = i64::try_from(val.rotate_left(bits)); match rotate_result { - Ok(val) => Value::Int { val, span }, - Err(_) => Value::Error { - error: Box::new(ShellError::GenericError( + Ok(val) => Value::int(val, span), + Err(_) => Value::error( + ShellError::GenericError( "Rotate left result beyond the range of 64 bit signed number".to_string(), format!( "{val} of the specified number of bytes rotate left {bits} bits exceed limit" @@ -116,15 +116,16 @@ where Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { use InputNumType::*; // let bits = (((bits % 64) + 64) % 64) as u32; let bits = bits as u32; @@ -142,15 +143,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs index 70e3a3ade..fa5ae8b4e 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs @@ -91,14 +91,14 @@ impl Command for BitsRor { Example { description: "Rotate right a list of numbers of one byte", example: "[15 33 92] | bits ror 2 -n '1'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(195), Value::test_int(72), Value::test_int(23), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -110,9 +110,9 @@ where { let rotate_result = i64::try_from(val.rotate_right(bits)); match rotate_result { - Ok(val) => Value::Int { val, span }, - Err(_) => Value::Error { - error: Box::new(ShellError::GenericError( + Ok(val) => Value::int(val, span), + Err(_) => Value::error( + ShellError::GenericError( "Rotate right result beyond the range of 64 bit signed number".to_string(), format!( "{val} of the specified number of bytes rotate right {bits} bits exceed limit" @@ -120,15 +120,16 @@ where Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { use InputNumType::*; // let bits = (((bits % 64) + 64) % 64) as u32; let bits = bits as u32; @@ -146,15 +147,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs index beff36cd3..884f831eb 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs @@ -101,10 +101,10 @@ impl Command for BitsShl { Example { description: "Shift left a list of numbers", example: "[5 3 2] | bits shl 2", - result: Some(Value::List { - vals: vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(20), Value::test_int(12), Value::test_int(8)], + Span::test_data(), + )), }, ] } @@ -118,9 +118,9 @@ where Some(val) => { let shift_result = i64::try_from(val); match shift_result { - Ok(val) => Value::Int { val, span }, - Err(_) => Value::Error { - error: Box::new(ShellError::GenericError( + Ok(val) => Value::int( val, span ), + Err(_) => Value::error( + ShellError::GenericError( "Shift left result beyond the range of 64 bit signed number".to_string(), format!( "{val} of the specified number of bytes shift left {bits} bits exceed limit" @@ -128,27 +128,28 @@ where Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } - None => Value::Error { - error: Box::new(ShellError::GenericError( + None => Value::error( + ShellError::GenericError( "Shift left failed".to_string(), format!("{val} shift left {bits} bits failed, you may shift too many bits"), Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { use InputNumType::*; // let bits = (((bits % 64) + 64) % 64) as u32; let bits = bits as u32; @@ -166,15 +167,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs index e8af586e7..d2696e255 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs @@ -91,10 +91,10 @@ impl Command for BitsShr { Example { description: "Shift right a list of numbers", example: "[15 35 2] | bits shr 2", - result: Some(Value::List { - vals: vec![Value::test_int(3), Value::test_int(8), Value::test_int(0)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(3), Value::test_int(8), Value::test_int(0)], + Span::test_data(), + )), }, ] } @@ -108,9 +108,9 @@ where Some(val) => { let shift_result = i64::try_from(val); match shift_result { - Ok(val) => Value::Int { val, span }, - Err(_) => Value::Error { - error: Box::new(ShellError::GenericError( + Ok(val) => Value::int( val, span ), + Err(_) => Value::error( + ShellError::GenericError( "Shift right result beyond the range of 64 bit signed number".to_string(), format!( "{val} of the specified number of bytes shift right {bits} bits exceed limit" @@ -118,27 +118,28 @@ where Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } - None => Value::Error { - error: Box::new(ShellError::GenericError( + None => Value::error( + ShellError::GenericError( "Shift right failed".to_string(), format!("{val} shift right {bits} bits failed, you may shift too many bits"), Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: NumberBytes) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { use InputNumType::*; // let bits = (((bits % 64) + 64) % 64) as u32; let bits = bits as u32; @@ -156,15 +157,15 @@ fn operate(value: Value, bits: usize, head: Span, signed: bool, number_size: Num } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/bits/xor.rs b/crates/nu-cmd-extra/src/extra/bits/xor.rs index 73805c447..a6ece2e65 100644 --- a/crates/nu-cmd-extra/src/extra/bits/xor.rs +++ b/crates/nu-cmd-extra/src/extra/bits/xor.rs @@ -67,32 +67,30 @@ impl Command for BitsXor { Example { description: "Apply logical xor to a list of numbers", example: "[8 3 2] | bits xor 2", - result: Some(Value::List { - vals: vec![Value::test_int(10), Value::test_int(1), Value::test_int(0)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(10), Value::test_int(1), Value::test_int(0)], + Span::test_data(), + )), }, ] } } fn operate(value: Value, target: i64, head: Span) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => Value::Int { - val: val ^ target, - span, - }, + Value::Int { val, .. } => Value::int(val ^ target, span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/conversions/fmt.rs b/crates/nu-cmd-extra/src/extra/conversions/fmt.rs index d90aadb9d..9b8b1171b 100644 --- a/crates/nu-cmd-extra/src/extra/conversions/fmt.rs +++ b/crates/nu-cmd-extra/src/extra/conversions/fmt.rs @@ -86,15 +86,15 @@ fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { Value::Filesize { val, .. } => fmt_it(*val, span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "float , integer or filesize".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/filters/each_while.rs b/crates/nu-cmd-extra/src/extra/filters/each_while.rs index 2da08aa0a..6b0f012b1 100644 --- a/crates/nu-cmd-extra/src/extra/filters/each_while.rs +++ b/crates/nu-cmd-extra/src/extra/filters/each_while.rs @@ -50,26 +50,20 @@ impl Command for EachWhile { Example { example: "[1 2 3 2 1] | each while {|e| if $e < 3 { $e * 2 } }", description: "Produces a list of each element before the 3, doubled", - result: Some(Value::List { - vals: stream_test_1, - span: Span::test_data(), - }), + result: Some(Value::list(stream_test_1, Span::test_data())), }, Example { example: r#"[1 2 stop 3 4] | each while {|e| if $e != 'stop' { $"Output: ($e)" } }"#, description: "Output elements until reaching 'stop'", - result: Some(Value::List { - vals: stream_test_2, - span: Span::test_data(), - }), + result: Some(Value::list(stream_test_2, Span::test_data())), }, Example { example: r#"[1 2 3] | enumerate | each while {|e| if $e.item < 2 { $"value ($e.item) at ($e.index)!"} }"#, description: "Iterate over each element, printing the matching value and its index", - result: Some(Value::List { - vals: vec![Value::test_string("value 1 at 0!")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("value 1 at 0!")], + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs b/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs index 4ae803e7c..1e584bb85 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/mod.rs @@ -21,8 +21,9 @@ fn vertical_rotate_value( by: Option, direction: VerticalDirection, ) -> Result { + let span = value.span(); match value { - Value::List { mut vals, span } => { + Value::List { mut vals, .. } => { let rotations = by.map(|n| n % vals.len()).unwrap_or(1); let values = vals.as_mut_slice(); @@ -31,10 +32,7 @@ fn vertical_rotate_value( VerticalDirection::Down => values.rotate_right(rotations), } - Ok(Value::List { - vals: values.to_owned(), - span, - }) + Ok(Value::list(values.to_owned(), span)) } _ => Err(ShellError::TypeMismatch { err_message: "list".to_string(), @@ -54,10 +52,10 @@ fn horizontal_rotate_value( cells_only: bool, direction: &HorizontalDirection, ) -> Result { + let span = value.span(); match value { Value::Record { - val: mut record, - span, + val: mut record, .. } => { let rotations = by.map(|n| n % record.len()).unwrap_or(1); @@ -75,13 +73,13 @@ fn horizontal_rotate_value( Ok(Value::record(record, span)) } - Value::List { vals, span } => { + Value::List { vals, .. } => { let values = vals .into_iter() .map(|value| horizontal_rotate_value(value, by, cells_only, direction)) .collect::, ShellError>>()?; - Ok(Value::List { vals: values, span }) + Ok(Value::list(values, span)) } _ => Err(ShellError::TypeMismatch { err_message: "record".to_string(), diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs index b3e8cd0f4..a4de6cc1c 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_.rs @@ -36,16 +36,16 @@ impl Command for Roll { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Roll.signature(), &Roll.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_down.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_down.rs index ba2303fdc..92819e41a 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_down.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_down.rs @@ -37,8 +37,8 @@ impl Command for RollDown { vec![Example { description: "Rolls rows down of a table", example: "[[a b]; [1 2] [3 4] [5 6]] | roll down", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: columns.clone(), vals: vec![Value::test_int(5), Value::test_int(6)], @@ -52,8 +52,8 @@ impl Command for RollDown { vals: vec![Value::test_int(3), Value::test_int(4)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs index 021b82e40..e49ca7f6d 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_left.rs @@ -59,8 +59,8 @@ impl Command for RollLeft { Example { description: "Rolls columns of a table to the left", example: "[[a b c]; [1 2 3] [4 5 6]] | roll left", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: rotated_columns.clone(), vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(1)], @@ -70,14 +70,14 @@ impl Command for RollLeft { vals: vec![Value::test_int(5), Value::test_int(6), Value::test_int(4)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rolls columns to the left without changing column names", example: "[[a b c]; [1 2 3] [4 5 6]] | roll left --cells-only", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: columns.clone(), vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(1)], @@ -87,8 +87,8 @@ impl Command for RollLeft { vals: vec![Value::test_int(5), Value::test_int(6), Value::test_int(4)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs index d35e13608..6689cc4d7 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_right.rs @@ -59,8 +59,8 @@ impl Command for RollRight { Example { description: "Rolls columns to the right", example: "[[a b c]; [1 2 3] [4 5 6]] | roll right", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: rotated_columns.clone(), vals: vec![Value::test_int(3), Value::test_int(1), Value::test_int(2)], @@ -70,14 +70,14 @@ impl Command for RollRight { vals: vec![Value::test_int(6), Value::test_int(4), Value::test_int(5)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rolls columns to the right with fixed headers", example: "[[a b c]; [1 2 3] [4 5 6]] | roll right --cells-only", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: columns.clone(), vals: vec![Value::test_int(3), Value::test_int(1), Value::test_int(2)], @@ -87,8 +87,8 @@ impl Command for RollRight { vals: vec![Value::test_int(6), Value::test_int(4), Value::test_int(5)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/filters/roll/roll_up.rs b/crates/nu-cmd-extra/src/extra/filters/roll/roll_up.rs index 963c5ccc5..e51680ad1 100644 --- a/crates/nu-cmd-extra/src/extra/filters/roll/roll_up.rs +++ b/crates/nu-cmd-extra/src/extra/filters/roll/roll_up.rs @@ -37,8 +37,8 @@ impl Command for RollUp { vec![Example { description: "Rolls rows up", example: "[[a b]; [1 2] [3 4] [5 6]] | roll up", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: columns.clone(), vals: vec![Value::test_int(3), Value::test_int(4)], @@ -52,8 +52,8 @@ impl Command for RollUp { vals: vec![Value::test_int(1), Value::test_int(2)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } diff --git a/crates/nu-cmd-extra/src/extra/filters/rotate.rs b/crates/nu-cmd-extra/src/extra/filters/rotate.rs index 43fced6fe..97e5ec0dd 100644 --- a/crates/nu-cmd-extra/src/extra/filters/rotate.rs +++ b/crates/nu-cmd-extra/src/extra/filters/rotate.rs @@ -38,8 +38,7 @@ impl Command for Rotate { Example { description: "Rotate a record clockwise, producing a table (like `transpose` but with column order reversed)", example: "{a:1, b:2} | rotate", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list(vec![ Value::test_record(Record { cols: vec!["column0".to_string(), "column1".to_string()], vals: vec![Value::test_int(1), Value::test_string("a")], @@ -49,14 +48,14 @@ impl Command for Rotate { vals: vec![Value::test_int(2), Value::test_string("b")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rotate 2x3 table clockwise", example: "[[a b]; [1 2] [3 4] [5 6]] | rotate", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec![ "column0".to_string(), @@ -86,14 +85,14 @@ impl Command for Rotate { ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rotate table clockwise and change columns names", example: "[[a b]; [1 2]] | rotate col_a col_b", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["col_a".to_string(), "col_b".to_string()], vals: vec![Value::test_int(1), Value::test_string("a")], @@ -103,14 +102,14 @@ impl Command for Rotate { vals: vec![Value::test_int(2), Value::test_string("b")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rotate table counter clockwise", example: "[[a b]; [1 2]] | rotate --ccw", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["column0".to_string(), "column1".to_string()], vals: vec![Value::test_string("b"), Value::test_int(2)], @@ -120,14 +119,14 @@ impl Command for Rotate { vals: vec![Value::test_string("a"), Value::test_int(1)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rotate table counter-clockwise", example: "[[a b]; [1 2] [3 4] [5 6]] | rotate --ccw", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec![ "column0".to_string(), @@ -157,14 +156,14 @@ impl Command for Rotate { ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rotate table counter-clockwise and change columns names", example: "[[a b]; [1 2]] | rotate --ccw col_a col_b", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["col_a".to_string(), "col_b".to_string()], vals: vec![Value::test_string("b"), Value::test_int(2)], @@ -174,8 +173,8 @@ impl Command for Rotate { vals: vec![Value::test_string("a"), Value::test_int(1)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -213,6 +212,7 @@ pub fn rotate( if !values.is_empty() { for val in values.into_iter() { + let span = val.span(); match val { Value::Record { val: record, .. } => { old_column_names = record.cols; @@ -226,9 +226,9 @@ pub fn rotate( new_values.push(v); } } - Value::String { val, span } => { + Value::String { val, .. } => { not_a_record = true; - new_values.push(Value::String { val, span }) + new_values.push(Value::string(val, span)) } x => { not_a_record = true; @@ -273,16 +273,16 @@ pub fn rotate( } if not_a_record { - return Ok(Value::List { - vals: vec![Value::record( + return Ok(Value::list( + vec![Value::record( Record { cols: new_column_names, vals: new_values, }, call.head, )], - span: call.head, - } + call.head, + ) .into_pipeline_data() .set_metadata(metadata)); } @@ -332,12 +332,9 @@ pub fn rotate( )) } - Ok(Value::List { - vals: final_values, - span: call.head, - } - .into_pipeline_data() - .set_metadata(metadata)) + Ok(Value::list(final_values, call.head) + .into_pipeline_data() + .set_metadata(metadata)) } #[cfg(test)] diff --git a/crates/nu-cmd-extra/src/extra/filters/update_cells.rs b/crates/nu-cmd-extra/src/extra/filters/update_cells.rs index 458261b21..0f56b04ff 100644 --- a/crates/nu-cmd-extra/src/extra/filters/update_cells.rs +++ b/crates/nu-cmd-extra/src/extra/filters/update_cells.rs @@ -51,8 +51,8 @@ impl Command for UpdateCells { $value } }"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec![ "2021-04-16".into(), "2021-06-10".into(), @@ -72,8 +72,8 @@ impl Command for UpdateCells { Value::test_string(""), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Update the zero value cells to empty strings in 2 last columns.", @@ -87,8 +87,8 @@ impl Command for UpdateCells { $value } }"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec![ "2021-04-16".into(), "2021-06-10".into(), @@ -108,8 +108,8 @@ impl Command for UpdateCells { Value::test_string(""), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -191,8 +191,9 @@ impl Iterator for UpdateCellIterator { } } + let span = val.span(); match val { - Value::Record { val, span } => Some(Value::record( + Value::Record { val, .. } => Some(Value::record( val.into_iter() .map(|(col, val)| match &self.columns { Some(cols) if !cols.contains(&col) => (col, val), @@ -251,10 +252,7 @@ fn process_cell( redirect_stderr, ) { Ok(pd) => pd.into_value(span), - Err(e) => Value::Error { - error: Box::new(e), - span, - }, + Err(e) => Value::error(e, span), } } diff --git a/crates/nu-cmd-extra/src/extra/formats/to/html.rs b/crates/nu-cmd-extra/src/extra/formats/to/html.rs index b7b2ccada..83cfae804 100644 --- a/crates/nu-cmd-extra/src/extra/formats/to/html.rs +++ b/crates/nu-cmd-extra/src/extra/formats/to/html.rs @@ -288,13 +288,13 @@ fn to_html( ) }) .collect(); - return Ok(Value::List { - vals: result, - span: head, - } - .into_pipeline_data_with_metadata(Box::new(PipelineMetadata { - data_source: DataSource::HtmlThemes, - }))); + return Ok( + Value::list(result, head).into_pipeline_data_with_metadata(Box::new( + PipelineMetadata { + data_source: DataSource::HtmlThemes, + }, + )), + ); } else { let theme_span = match &theme { Some(v) => v.span, @@ -403,7 +403,8 @@ fn html_table(table: Vec, headers: Vec, config: &Config) -> Strin output_string.push_str(""); for row in table { - if let Value::Record { span, .. } = row { + let span = row.span(); + if let Value::Record { .. } = row { output_string.push_str(""); for header in &headers { let data = row.get_data_by_key(header); diff --git a/crates/nu-cmd-extra/src/extra/math/arccos.rs b/crates/nu-cmd-extra/src/extra/math/arccos.rs index 17e9cc35b..aa34ef092 100644 --- a/crates/nu-cmd-extra/src/extra/math/arccos.rs +++ b/crates/nu-cmd-extra/src/extra/math/arccos.rs @@ -70,9 +70,10 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, use_degrees: bool) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; @@ -80,29 +81,29 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value { let val = val.acos(); let val = if use_degrees { val.to_degrees() } else { val }; - Value::Float { val, span } + Value::float(val, span) } else { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Value::error( + ShellError::UnsupportedInput( "'arccos' undefined for values outside the closed interval [-1, 1].".into(), "value originates from here".into(), head, span, - )), + ), span, - } + ) } } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/arccosh.rs b/crates/nu-cmd-extra/src/extra/math/arccosh.rs index 19cb08cf9..d5f224453 100644 --- a/crates/nu-cmd-extra/src/extra/math/arccosh.rs +++ b/crates/nu-cmd-extra/src/extra/math/arccosh.rs @@ -61,38 +61,39 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; if (1.0..).contains(&val) { let val = val.acosh(); - Value::Float { val, span } + Value::float(val, span) } else { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Value::error( + ShellError::UnsupportedInput( "'arccosh' undefined for values below 1.".into(), "value originates from here".into(), head, span, - )), + ), span, - } + ) } } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/arcsin.rs b/crates/nu-cmd-extra/src/extra/math/arcsin.rs index 8253e509c..e99e3c558 100644 --- a/crates/nu-cmd-extra/src/extra/math/arcsin.rs +++ b/crates/nu-cmd-extra/src/extra/math/arcsin.rs @@ -71,9 +71,10 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, use_degrees: bool) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; @@ -81,29 +82,29 @@ fn operate(value: Value, head: Span, use_degrees: bool) -> Value { let val = val.asin(); let val = if use_degrees { val.to_degrees() } else { val }; - Value::Float { val, span } + Value::float(val, span) } else { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Value::error( + ShellError::UnsupportedInput( "'arcsin' undefined for values outside the closed interval [-1, 1].".into(), "value originates from here".into(), head, span, - )), + ), span, - } + ) } } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/arcsinh.rs b/crates/nu-cmd-extra/src/extra/math/arcsinh.rs index 7e627c0c2..80069f3d6 100644 --- a/crates/nu-cmd-extra/src/extra/math/arcsinh.rs +++ b/crates/nu-cmd-extra/src/extra/math/arcsinh.rs @@ -61,26 +61,27 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; let val = val.asinh(); - Value::Float { val, span } + Value::float(val, span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/arctan.rs b/crates/nu-cmd-extra/src/extra/math/arctan.rs index 955764885..cae303cab 100644 --- a/crates/nu-cmd-extra/src/extra/math/arctan.rs +++ b/crates/nu-cmd-extra/src/extra/math/arctan.rs @@ -71,27 +71,28 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, use_degrees: bool) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; let val = val.atan(); let val = if use_degrees { val.to_degrees() } else { val }; - Value::Float { val, span } + Value::float(val, span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/arctanh.rs b/crates/nu-cmd-extra/src/extra/math/arctanh.rs index dc0984b19..0bb2f4d4a 100644 --- a/crates/nu-cmd-extra/src/extra/math/arctanh.rs +++ b/crates/nu-cmd-extra/src/extra/math/arctanh.rs @@ -61,38 +61,39 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; if (-1.0..=1.0).contains(&val) { let val = val.atanh(); - Value::Float { val, span } + Value::float(val, span) } else { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Value::error( + ShellError::UnsupportedInput( "'arctanh' undefined for values outside the open interval (-1, 1).".into(), "value originates from here".into(), head, span, - )), - span: head, - } + ), + head, + ) } } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/cos.rs b/crates/nu-cmd-extra/src/extra/math/cos.rs index a211a834d..75b17de4f 100644 --- a/crates/nu-cmd-extra/src/extra/math/cos.rs +++ b/crates/nu-cmd-extra/src/extra/math/cos.rs @@ -60,16 +60,16 @@ impl Command for SubCommand { Example { description: "Apply the cosine to a list of angles in degrees", example: "[0 90 180 270 360] | math cos -d", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_float(1f64), Value::test_float(0f64), Value::test_float(-1f64), Value::test_float(0f64), Value::test_float(1f64), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -78,29 +78,27 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, use_degrees: bool) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; let val = if use_degrees { val.to_radians() } else { val }; - Value::Float { - val: val.cos(), - span, - } + Value::float(val.cos(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/cosh.rs b/crates/nu-cmd-extra/src/extra/math/cosh.rs index 1d7f2fd2d..b9eae5d27 100644 --- a/crates/nu-cmd-extra/src/extra/math/cosh.rs +++ b/crates/nu-cmd-extra/src/extra/math/cosh.rs @@ -62,27 +62,26 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); + let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; - Value::Float { - val: val.cosh(), - span, - } + Value::float(val.cosh(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/exp.rs b/crates/nu-cmd-extra/src/extra/math/exp.rs index faa586226..1c19b0e00 100644 --- a/crates/nu-cmd-extra/src/extra/math/exp.rs +++ b/crates/nu-cmd-extra/src/extra/math/exp.rs @@ -68,27 +68,25 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; - Value::Float { - val: val.exp(), - span, - } + Value::float(val.exp(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/ln.rs b/crates/nu-cmd-extra/src/extra/math/ln.rs index 3880cf09c..cd953978f 100644 --- a/crates/nu-cmd-extra/src/extra/math/ln.rs +++ b/crates/nu-cmd-extra/src/extra/math/ln.rs @@ -61,38 +61,39 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; if val > 0.0 { let val = val.ln(); - Value::Float { val, span } + Value::float(val, span) } else { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Value::error( + ShellError::UnsupportedInput( "'ln' undefined for values outside the open interval (0, Inf).".into(), "value originates from here".into(), head, span, - )), + ), span, - } + ) } } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/sin.rs b/crates/nu-cmd-extra/src/extra/math/sin.rs index d4f1a4d78..def2d7ded 100644 --- a/crates/nu-cmd-extra/src/extra/math/sin.rs +++ b/crates/nu-cmd-extra/src/extra/math/sin.rs @@ -60,16 +60,16 @@ impl Command for SubCommand { Example { description: "Apply the sine to a list of angles in degrees", example: "[0 90 180 270 360] | math sin -d | math round --precision 4", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_float(0f64), Value::test_float(1f64), Value::test_float(0f64), Value::test_float(-1f64), Value::test_float(0f64), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -78,29 +78,27 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, use_degrees: bool) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; let val = if use_degrees { val.to_radians() } else { val }; - Value::Float { - val: val.sin(), - span, - } + Value::float(val.sin(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/sinh.rs b/crates/nu-cmd-extra/src/extra/math/sinh.rs index acfaebc25..ff92dc9a3 100644 --- a/crates/nu-cmd-extra/src/extra/math/sinh.rs +++ b/crates/nu-cmd-extra/src/extra/math/sinh.rs @@ -62,27 +62,25 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; - Value::Float { - val: val.sinh(), - span, - } + Value::float(val.sinh(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/tan.rs b/crates/nu-cmd-extra/src/extra/math/tan.rs index 0d8b87f89..b24c17ddf 100644 --- a/crates/nu-cmd-extra/src/extra/math/tan.rs +++ b/crates/nu-cmd-extra/src/extra/math/tan.rs @@ -60,14 +60,14 @@ impl Command for SubCommand { Example { description: "Apply the tangent to a list of angles in degrees", example: "[-45 0 45] | math tan -d", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_float(-1f64), Value::test_float(0f64), Value::test_float(1f64), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -76,29 +76,27 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, use_degrees: bool) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; let val = if use_degrees { val.to_radians() } else { val }; - Value::Float { - val: val.tan(), - span, - } + Value::float(val.tan(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/math/tanh.rs b/crates/nu-cmd-extra/src/extra/math/tanh.rs index 15331762a..aec6d8b40 100644 --- a/crates/nu-cmd-extra/src/extra/math/tanh.rs +++ b/crates/nu-cmd-extra/src/extra/math/tanh.rs @@ -61,27 +61,25 @@ impl Command for SubCommand { fn operate(value: Value, head: Span) -> Value { match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { + let span = numeric.span(); let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; - Value::Float { - val: val.tanh(), - span, - } + Value::float(val.tanh(), span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/platform/ansi/gradient.rs b/crates/nu-cmd-extra/src/extra/platform/ansi/gradient.rs index 3237222af..325dc085f 100644 --- a/crates/nu-cmd-extra/src/extra/platform/ansi/gradient.rs +++ b/crates/nu-cmd-extra/src/extra/platform/ansi/gradient.rs @@ -138,10 +138,7 @@ fn operate( Box::new(move |old| action(old, fgs_hex, fge_hex, bgs_hex, bge_hex, head)), ); if let Err(error) = r { - return Value::Error { - error: Box::new(error), - span: head, - }; + return Value::error(error, head); } } ret @@ -159,20 +156,20 @@ fn action( bg_end: Option, command_span: Span, ) -> Value { + let span = input.span(); match input { - Value::String { val, span } => { - let span = *span; + Value::String { val, .. } => { match (fg_start, fg_end, bg_start, bg_end) { (None, None, None, None) => { // Error - no colors - Value::Error { - error: Box::new(ShellError::MissingParameter { + Value::error( + ShellError::MissingParameter { param_name: "please supply foreground and/or background color parameters".into(), span: command_span, - }), - span: command_span, - } + }, + span, + ) } (None, None, None, Some(bg_end)) => { // Error - missing bg_start, so assume black @@ -294,13 +291,13 @@ fn action( other => { let got = format!("value is {}, not string", other.get_type()); - Value::Error { - error: Box::new(ShellError::TypeMismatch { + Value::error( + ShellError::TypeMismatch { err_message: got, span: other.span(), - }), - span: other.span(), - } + }, + other.span(), + ) } } } diff --git a/crates/nu-cmd-extra/src/extra/platform/ansi/link.rs b/crates/nu-cmd-extra/src/extra/platform/ansi/link.rs index 136740524..f2db38e8e 100644 --- a/crates/nu-cmd-extra/src/extra/platform/ansi/link.rs +++ b/crates/nu-cmd-extra/src/extra/platform/ansi/link.rs @@ -118,32 +118,30 @@ fn process_each_path( for path in column_paths { let ret = value.update_cell_path(&path.members, Box::new(|v| process_value(v, text))); if let Err(error) = ret { - return Value::Error { - error: Box::new(error), - span: command_span, - }; + return Value::error(error, command_span); } } value } fn process_value(value: &Value, text: &Option) -> Value { + let span = value.span(); match value { - Value::String { val, span } => { + Value::String { val, .. } => { let text = text.as_deref().unwrap_or(val.as_str()); let result = add_osc_link(text, val.as_str()); - Value::string(result, *span) + Value::string(result, span) } other => { let got = format!("value is {}, not string", other.get_type()); - Value::Error { - error: Box::new(ShellError::TypeMismatch { + Value::error( + ShellError::TypeMismatch { err_message: got, span: other.span(), - }), - span: other.span(), - } + }, + other.span(), + ) } } } diff --git a/crates/nu-cmd-extra/src/extra/strings/encode_decode/hex.rs b/crates/nu-cmd-extra/src/extra/strings/encode_decode/hex.rs index 826e40c07..fad4521fc 100644 --- a/crates/nu-cmd-extra/src/extra/strings/encode_decode/hex.rs +++ b/crates/nu-cmd-extra/src/extra/strings/encode_decode/hex.rs @@ -107,62 +107,60 @@ fn action( Value::Error { .. } => input.clone(), Value::Binary { val, .. } => match hex_config.action_type { ActionType::Encode => Value::string(hex_encode(val.as_ref()), command_span), - ActionType::Decode => Value::Error { - error: Box::new(ShellError::UnsupportedInput( + ActionType::Decode => Value::error( + ShellError::UnsupportedInput( "Binary data can only be encoded".to_string(), "value originates from here".into(), command_span, // This line requires the Value::Error {} match above. input.span(), - )), - span: command_span, - }, + ), + command_span, + ), }, Value::String { val, .. } => { match hex_config.action_type { - ActionType::Encode => Value::Error { - error: Box::new(ShellError::UnsupportedInput( + ActionType::Encode => Value::error( + ShellError::UnsupportedInput( "String value can only be decoded".to_string(), "value originates from here".into(), command_span, // This line requires the Value::Error {} match above. input.span(), - )), - span: command_span, - }, + ), + command_span, + ), ActionType::Decode => match hex_decode(val.as_ref()) { Ok(decoded_value) => Value::binary(decoded_value, command_span), - Err(HexDecodingError::InvalidLength(len)) => Value::Error { - error: Box::new(ShellError::GenericError( + Err(HexDecodingError::InvalidLength(len)) => Value::error(ShellError::GenericError( "value could not be hex decoded".to_string(), format!("invalid hex input length: {len}. The length should be even"), Some(command_span), None, Vec::new(), - )), - span: command_span, - }, - Err(HexDecodingError::InvalidDigit(index, digit)) => Value::Error { - error: Box::new(ShellError::GenericError( + ), + command_span, + ), + Err(HexDecodingError::InvalidDigit(index, digit)) => Value::error(ShellError::GenericError( "value could not be hex decoded".to_string(), format!("invalid hex digit: '{digit}' at index {index}. Only 0-9, A-F, a-f are allowed in hex encoding"), Some(command_span), None, Vec::new(), - )), - span: command_span, - }, + ), + command_span, + ), }, } } - other => Value::Error { - error: Box::new(ShellError::TypeMismatch { + other => Value::error( + ShellError::TypeMismatch { err_message: format!("string or binary, not {}", other.get_type()), span: other.span(), - }), - span: other.span(), - }, + }, + other.span(), + ), } } diff --git a/crates/nu-cmd-extra/src/extra/strings/format/command.rs b/crates/nu-cmd-extra/src/extra/strings/format/command.rs index 13497a2a6..94936ad23 100644 --- a/crates/nu-cmd-extra/src/extra/strings/format/command.rs +++ b/crates/nu-cmd-extra/src/extra/strings/format/command.rs @@ -86,10 +86,10 @@ impl Command for Format { Example { description: "Print elements from some columns of a table", example: "[[col1, col2]; [v1, v2] [v3, v4]] | format '{col2}'", - result: Some(Value::List { - vals: vec![Value::test_string("v2"), Value::test_string("v4")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("v2"), Value::test_string("v4")], + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs index b49d74bb2..2ad833114 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs @@ -73,13 +73,13 @@ impl Command for SubCommand { Example { description: "convert a column from a table to camelCase", example: r#"[[lang, gems]; [nu_test, 100]] | str camel-case lang"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["lang".to_string(), "gems".to_string()], vals: vec![Value::test_string("nuTest"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs index d869d0230..1a8356a64 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs @@ -73,13 +73,13 @@ impl Command for SubCommand { Example { description: "convert a column from a table to kebab-case", example: r#"[[lang, gems]; [nuTest, 100]] | str kebab-case lang"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["lang".to_string(), "gems".to_string()], vals: vec![Value::test_string("nu-test"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs index 4923795ac..83617ab09 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs @@ -57,19 +57,16 @@ where { let case_operation = args.case_operation; match input { - Value::String { val, .. } => Value::String { - val: case_operation(val), - span: head, - }, + Value::String { val, .. } => Value::string(case_operation(val), head), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs index b694350f6..7d7d3cc18 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs @@ -73,13 +73,13 @@ impl Command for SubCommand { Example { description: "convert a column from a table to PascalCase", example: r#"[[lang, gems]; [nu_test, 100]] | str pascal-case lang"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["lang".to_string(), "gems".to_string()], vals: vec![Value::test_string("NuTest"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs index f78b029b8..426f00cdb 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs @@ -73,13 +73,13 @@ impl Command for SubCommand { Example { description: "convert a column from a table to SCREAMING_SNAKE_CASE", example: r#"[[lang, gems]; [nu_test, 100]] | str screaming-snake-case lang"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["lang".to_string(), "gems".to_string()], vals: vec![Value::test_string("NU_TEST"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs index 64d2b399e..de9a45df3 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs @@ -72,13 +72,13 @@ impl Command for SubCommand { Example { description: "convert a column from a table to snake_case", example: r#"[[lang, gems]; [nuTest, 100]] | str snake-case lang"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["lang".to_string(), "gems".to_string()], vals: vec![Value::test_string("nu_test"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs index 6cfd59b71..a0731972a 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs @@ -34,16 +34,16 @@ impl Command for Str { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Str.signature(), &Str.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs index 16dd30f03..73b7e769a 100644 --- a/crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs @@ -68,13 +68,13 @@ impl Command for SubCommand { Example { description: "convert a column from a table to Title Case", example: r#"[[title, count]; ['nu test', 100]] | str title-case title"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["title".to_string(), "count".to_string()], vals: vec![Value::test_string("Nu Test"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-cmd-lang/src/core_commands/describe.rs b/crates/nu-cmd-lang/src/core_commands/describe.rs index 86f0f1496..48b04cd9a 100644 --- a/crates/nu-cmd-lang/src/core_commands/describe.rs +++ b/crates/nu-cmd-lang/src/core_commands/describe.rs @@ -106,11 +106,7 @@ fn run(call: &Call, input: PipelineData) -> Result { } }; - Ok(Value::String { - val: description, - span: head, - } - .into_pipeline_data()) + Ok(Value::string(description, head).into_pipeline_data()) } #[cfg(test)] diff --git a/crates/nu-cmd-lang/src/core_commands/do_.rs b/crates/nu-cmd-lang/src/core_commands/do_.rs index 48c0751f8..413775f2c 100644 --- a/crates/nu-cmd-lang/src/core_commands/do_.rs +++ b/crates/nu-cmd-lang/src/core_commands/do_.rs @@ -100,10 +100,7 @@ impl Command for Do { param .var_id .expect("Internal error: rest positional parameter lacks var_id"), - Value::List { - vals: rest_items, - span, - }, + Value::list(rest_items, span), ) } } diff --git a/crates/nu-cmd-lang/src/core_commands/echo.rs b/crates/nu-cmd-lang/src/core_commands/echo.rs index 7056c0921..b3dad7f46 100644 --- a/crates/nu-cmd-lang/src/core_commands/echo.rs +++ b/crates/nu-cmd-lang/src/core_commands/echo.rs @@ -61,10 +61,10 @@ little reason to use this over just writing the values as-is."# Example { description: "Put a list of numbers in the pipeline. This is the same as [1 2 3].", example: "echo 1 2 3", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], + Span::test_data(), + )), }, Example { description: diff --git a/crates/nu-cmd-lang/src/core_commands/error_make.rs b/crates/nu-cmd-lang/src/core_commands/error_make.rs index 3682ccb57..d6c9cfd3f 100644 --- a/crates/nu-cmd-lang/src/core_commands/error_make.rs +++ b/crates/nu-cmd-lang/src/core_commands/error_make.rs @@ -65,16 +65,16 @@ impl Command for ErrorMake { Example { description: "Create a simple custom error", example: r#"error make {msg: "my custom error message"}"#, - result: Some(Value::Error { - error: Box::new(ShellError::GenericError( + result: Some(Value::error( + ShellError::GenericError( "my custom error message".to_string(), "".to_string(), None, None, Vec::new(), - )), - span: Span::unknown(), - }), + ), + Span::unknown(), + )), }, Example { description: "Create a more complex custom error", @@ -86,16 +86,16 @@ impl Command for ErrorMake { end: 456 # not mandatory unless $.label.start is set } }"#, - result: Some(Value::Error { - error: Box::new(ShellError::GenericError( + result: Some(Value::error( + ShellError::GenericError( "my custom error message".to_string(), "my custom label text".to_string(), Some(Span::new(123, 456)), None, Vec::new(), - )), - span: Span::unknown(), - }), + ), + Span::unknown(), + )), }, Example { description: @@ -118,7 +118,8 @@ impl Command for ErrorMake { } fn make_error(value: &Value, throw_span: Option) -> Option { - if let Value::Record { span, .. } = &value { + let span = value.span(); + if let Value::Record { .. } = &value { let msg = value.get_data_by_key("msg"); let label = value.get_data_by_key("label"); @@ -203,7 +204,7 @@ fn make_error(value: &Value, throw_span: Option) -> Option { (None, _) => Some(ShellError::GenericError( "Unable to parse error format.".into(), "missing required member `$.msg`".into(), - Some(*span), + Some(span), None, Vec::new(), )), diff --git a/crates/nu-cmd-lang/src/core_commands/export.rs b/crates/nu-cmd-lang/src/core_commands/export.rs index 0147bb32c..7b8a94541 100644 --- a/crates/nu-cmd-lang/src/core_commands/export.rs +++ b/crates/nu-cmd-lang/src/core_commands/export.rs @@ -39,16 +39,16 @@ impl Command for ExportCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &ExportCommand.signature(), &ExportCommand.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } diff --git a/crates/nu-cmd-lang/src/core_commands/lazy_make.rs b/crates/nu-cmd-lang/src/core_commands/lazy_make.rs index 3762292d3..c7c1aab29 100644 --- a/crates/nu-cmd-lang/src/core_commands/lazy_make.rs +++ b/crates/nu-cmd-lang/src/core_commands/lazy_make.rs @@ -65,8 +65,8 @@ impl Command for LazyMake { .get_flag(engine_state, stack, "get-value")? .expect("required flag"); - Ok(Value::LazyRecord { - val: Box::new(NuLazyRecord { + Ok(Value::lazy_record( + Box::new(NuLazyRecord { engine_state: engine_state.clone(), stack: Arc::new(Mutex::new(stack.clone())), columns, @@ -74,7 +74,7 @@ impl Command for LazyMake { span, }), span, - } + ) .into_pipeline_data()) } @@ -118,10 +118,7 @@ impl<'a> LazyRecord<'a> for NuLazyRecord { fn get_column_value(&self, column: &str) -> Result { let block = self.engine_state.get_block(self.get_value.block_id); let mut stack = self.stack.lock().expect("lock must not be poisoned"); - let column_value = Value::String { - val: column.into(), - span: self.span, - }; + let column_value = Value::string(column, self.span); if let Some(var) = block.signature.get_positional(0) { if let Some(var_id) = &var.var_id { @@ -141,7 +138,7 @@ impl<'a> LazyRecord<'a> for NuLazyRecord { pipeline_result.map(|data| match data { PipelineData::Value(value, ..) => value, // TODO: Proper error handling. - _ => Value::Nothing { span: self.span }, + _ => Value::nothing(self.span), }) } @@ -150,9 +147,6 @@ impl<'a> LazyRecord<'a> for NuLazyRecord { } fn clone_value(&self, span: Span) -> Value { - Value::LazyRecord { - val: Box::new((*self).clone()), - span, - } + Value::lazy_record(Box::new((*self).clone()), span) } } diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/command.rs b/crates/nu-cmd-lang/src/core_commands/overlay/command.rs index 8459e7fee..d05669629 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/command.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/command.rs @@ -41,16 +41,16 @@ impl Command for Overlay { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Overlay.signature(), &[], engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-cmd-lang/src/core_commands/overlay/list.rs b/crates/nu-cmd-lang/src/core_commands/overlay/list.rs index de0321291..097cbc5a6 100644 --- a/crates/nu-cmd-lang/src/core_commands/overlay/list.rs +++ b/crates/nu-cmd-lang/src/core_commands/overlay/list.rs @@ -39,11 +39,7 @@ impl Command for OverlayList { .map(|s| Value::string(s, call.head)) .collect(); - Ok(Value::List { - vals: active_overlays_engine, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::list(active_overlays_engine, call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-cmd-lang/src/core_commands/scope/command.rs b/crates/nu-cmd-lang/src/core_commands/scope/command.rs index 9baa09aa4..930691f4a 100644 --- a/crates/nu-cmd-lang/src/core_commands/scope/command.rs +++ b/crates/nu-cmd-lang/src/core_commands/scope/command.rs @@ -35,16 +35,16 @@ impl Command for Scope { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Scope.signature(), &[], engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-color-config/src/color_config.rs b/crates/nu-color-config/src/color_config.rs index d339d56be..4519e4548 100644 --- a/crates/nu-color-config/src/color_config.rs +++ b/crates/nu-color-config/src/color_config.rs @@ -123,18 +123,9 @@ mod tests { let record = Record { cols: vec!["bg".to_string(), "fg".to_string(), "attr".to_string()], vals: vec![ - Value::String { - val: "red".to_string(), - span: Span::unknown(), - }, - Value::String { - val: "blue".to_string(), - span: Span::unknown(), - }, - Value::String { - val: "bold".to_string(), - span: Span::unknown(), - }, + Value::string("red", Span::unknown()), + Value::string("blue", Span::unknown()), + Value::string("bold", Span::unknown()), ], }; let expected_style = NuStyle { @@ -155,10 +146,7 @@ mod tests { let record = Record { cols: vec!["bg".to_string(), "invalid".to_string()], vals: vec![ - Value::String { - val: "green".to_string(), - span: Span::unknown(), - }, + Value::string("green", Span::unknown()), Value::nothing(Span::unknown()), ], }; @@ -174,10 +162,7 @@ mod tests { fn test_parse_map_entry() { let mut hm = HashMap::new(); let key = "test_key".to_owned(); - let value = Value::String { - val: "red".to_owned(), - span: Span::unknown(), - }; + let value = Value::string("red", Span::unknown()); parse_map_entry(&mut hm, &key, &value); assert_eq!(hm.get(&key), Some(&lookup_ansi_color_style("red"))); } diff --git a/crates/nu-color-config/src/style_computer.rs b/crates/nu-color-config/src/style_computer.rs index 03ea07c07..35f5a75cc 100644 --- a/crates/nu-color-config/src/style_computer.rs +++ b/crates/nu-color-config/src/style_computer.rs @@ -54,51 +54,57 @@ impl<'a> StyleComputer<'a> { // Static values require no computation. Some(ComputableStyle::Static(s)) => *s, // Closures are run here. - Some(ComputableStyle::Closure(Value::Closure { - val: block_id, - captures, - span, - })) => { - let block = self.engine_state.get_block(*block_id).clone(); - // Because captures_to_stack() clones, we don't need to use with_env() here - // (contrast with_env() usage in `each` or `do`). - let mut stack = self.stack.captures_to_stack(captures); + Some(ComputableStyle::Closure(v)) => { + let span = v.span(); + match v { + Value::Closure { + val: block_id, + captures, + .. + } => { + let block = self.engine_state.get_block(*block_id).clone(); + // Because captures_to_stack() clones, we don't need to use with_env() here + // (contrast with_env() usage in `each` or `do`). + let mut stack = self.stack.captures_to_stack(captures); - // Support 1-argument blocks as well as 0-argument blocks. - if let Some(var) = block.signature.get_positional(0) { - if let Some(var_id) = &var.var_id { - stack.add_var(*var_id, value.clone()); - } - } + // Support 1-argument blocks as well as 0-argument blocks. + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + stack.add_var(*var_id, value.clone()); + } + } - // Run the block. - match eval_block( - self.engine_state, - &mut stack, - &block, - value.clone().into_pipeline_data(), - false, - false, - ) { - Ok(v) => { - let value = v.into_value(*span); - // These should be the same color data forms supported by color_config. - match value { - Value::Record { .. } => color_record_to_nustyle(&value), - Value::String { val, .. } => lookup_ansi_color_style(&val), - _ => Style::default(), + // Run the block. + match eval_block( + self.engine_state, + &mut stack, + &block, + value.clone().into_pipeline_data(), + false, + false, + ) { + Ok(v) => { + let value = v.into_value(span); + // These should be the same color data forms supported by color_config. + match value { + Value::Record { .. } => color_record_to_nustyle(&value), + Value::String { val, .. } => lookup_ansi_color_style(&val), + _ => Style::default(), + } + } + // This is basically a copy of nu_cli::report_error(), but that isn't usable due to + // dependencies. While crudely spitting out a bunch of errors like this is not ideal, + // currently hook closure errors behave roughly the same. + Err(e) => { + eprintln!( + "Error: {:?}", + CliError(&e, &StateWorkingSet::new(self.engine_state)) + ); + Style::default() + } } } - // This is basically a copy of nu_cli::report_error(), but that isn't usable due to - // dependencies. While crudely spitting out a bunch of errors like this is not ideal, - // currently hook closure errors behave roughly the same. - Err(e) => { - eprintln!( - "Error: {:?}", - CliError(&e, &StateWorkingSet::new(self.engine_state)) - ); - Style::default() - } + _ => Style::default(), } } // There should be no other kinds of values (due to create_map() in config.rs filtering them out) diff --git a/crates/nu-command/src/bytes/add.rs b/crates/nu-command/src/bytes/add.rs index 2bbb07f4a..3cfd989c9 100644 --- a/crates/nu-command/src/bytes/add.rs +++ b/crates/nu-command/src/bytes/add.rs @@ -91,56 +91,50 @@ impl Command for BytesAdd { Example { description: "Add bytes `0x[AA]` to `0x[1F FF AA AA]`", example: "0x[1F FF AA AA] | bytes add 0x[AA]", - result: Some(Value::Binary { - val: vec![0xAA, 0x1F, 0xFF, 0xAA, 0xAA], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0xAA, 0x1F, 0xFF, 0xAA, 0xAA], + Span::test_data(), + )), }, Example { description: "Add bytes `0x[AA BB]` to `0x[1F FF AA AA]` at index 1", example: "0x[1F FF AA AA] | bytes add 0x[AA BB] -i 1", - result: Some(Value::Binary { - val: vec![0x1F, 0xAA, 0xBB, 0xFF, 0xAA, 0xAA], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x1F, 0xAA, 0xBB, 0xFF, 0xAA, 0xAA], + Span::test_data(), + )), }, Example { description: "Add bytes `0x[11]` to `0x[FF AA AA]` at the end", example: "0x[FF AA AA] | bytes add 0x[11] -e", - result: Some(Value::Binary { - val: vec![0xFF, 0xAA, 0xAA, 0x11], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0xFF, 0xAA, 0xAA, 0x11], + Span::test_data(), + )), }, Example { description: "Add bytes `0x[11 22 33]` to `0x[FF AA AA]` at the end, at index 1(the index is start from end)", example: "0x[FF AA BB] | bytes add 0x[11 22 33] -e -i 1", - result: Some(Value::Binary { - val: vec![0xFF, 0xAA, 0x11, 0x22, 0x33, 0xBB], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0xFF, 0xAA, 0x11, 0x22, 0x33, 0xBB], + Span::test_data(), + )), }, ] } } fn add(val: &Value, args: &Arguments, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => add_impl(val, args, *val_span), + Value::Binary { val, .. } => add_impl(val, args, val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } @@ -151,12 +145,12 @@ fn add_impl(input: &[u8], args: &Arguments, span: Span) -> Value { let mut added_data = args.added_data.clone(); let mut result = input.to_vec(); result.append(&mut added_data); - Value::Binary { val: result, span } + Value::binary(result, span) } else { let mut result = args.added_data.clone(); let mut input = input.to_vec(); result.append(&mut input); - Value::Binary { val: result, span } + Value::binary(result, span) } } Some(mut indx) => { @@ -175,7 +169,7 @@ fn add_impl(input: &[u8], args: &Arguments, span: Span) -> Value { result.append(&mut added_data); let mut after_data = input[inserted_index..].to_vec(); result.append(&mut after_data); - Value::Binary { val: result, span } + Value::binary(result, span) } } } diff --git a/crates/nu-command/src/bytes/at.rs b/crates/nu-command/src/bytes/at.rs index db024f814..4c1fcbf85 100644 --- a/crates/nu-command/src/bytes/at.rs +++ b/crates/nu-command/src/bytes/at.rs @@ -94,18 +94,12 @@ impl Command for BytesAt { Example { description: "Get a subbytes `0x[10 01]` from the bytes `0x[33 44 55 10 01 13]`", example: " 0x[33 44 55 10 01 13] | bytes at 3..<4", - result: Some(Value::Binary { - val: vec![0x10], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x10], Span::test_data())), }, Example { description: "Get a subbytes `0x[10 01 13]` from the bytes `0x[33 44 55 10 01 13]`", example: " 0x[33 44 55 10 01 13] | bytes at 3..6", - result: Some(Value::Binary { - val: vec![0x10, 0x01, 0x13], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x10, 0x01, 0x13], Span::test_data())), }, Example { description: "Get the remaining characters from a starting index", @@ -118,35 +112,26 @@ impl Command for BytesAt { Example { description: "Get the characters from the beginning until ending index", example: " 0x[33 44 55 10 01 13] | bytes at ..<4", - result: Some(Value::Binary { - val: vec![0x33, 0x44, 0x55, 0x10], - span: Span::test_data(), - }), + result: Some(Value::binary( + vec![0x33, 0x44, 0x55, 0x10], + Span::test_data(), + )), }, Example { description: "Or the characters from the beginning until ending index inside a table", example: r#" [[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes at 1.. ColB ColC"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string(), "ColC".to_string()], vals: vec![ - Value::Binary { - val: vec![0x11, 0x12, 0x13], - span: Span::test_data(), - }, - Value::Binary { - val: vec![0x15, 0x16], - span: Span::test_data(), - }, - Value::Binary { - val: vec![0x18, 0x19], - span: Span::test_data(), - }, + Value::binary(vec![0x11, 0x12, 0x13], Span::test_data()), + Value::binary(vec![0x15, 0x16], Span::test_data()), + Value::binary(vec![0x18, 0x19], Span::test_data()), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -169,51 +154,46 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { if start < len && end >= 0 { match start.cmp(&end) { - Ordering::Equal => Value::Binary { - val: vec![], - span: head, - }, - Ordering::Greater => Value::Error { - error: Box::new(ShellError::TypeMismatch { + Ordering::Equal => Value::binary(vec![], head), + Ordering::Greater => Value::error( + ShellError::TypeMismatch { err_message: "End must be greater than or equal to Start".to_string(), span: head, - }), - span: head, - }, - Ordering::Less => Value::Binary { - val: { - if end == isize::max_value() { - val.iter().skip(start as usize).copied().collect() - } else { - val.iter() - .skip(start as usize) - .take((end - start) as usize) - .copied() - .collect() - } }, - span: head, - }, + head, + ), + Ordering::Less => Value::binary( + if end == isize::max_value() { + val.iter() + .skip(start as usize) + .copied() + .collect::>() + } else { + val.iter() + .skip(start as usize) + .take((end - start) as usize) + .copied() + .collect() + }, + head, + ), } } else { - Value::Binary { - val: vec![], - span: head, - } + Value::binary(vec![], head) } } Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::UnsupportedInput( + other => Value::error( + ShellError::UnsupportedInput( "Only binary values are supported".into(), format!("input type: {:?}", other.get_type()), head, // This line requires the Value::Error match above. other.span(), - )), - span: head, - }, + ), + head, + ), } } diff --git a/crates/nu-command/src/bytes/build_.rs b/crates/nu-command/src/bytes/build_.rs index 4726ee155..15b4b2e78 100644 --- a/crates/nu-command/src/bytes/build_.rs +++ b/crates/nu-command/src/bytes/build_.rs @@ -33,10 +33,10 @@ impl Command for BytesBuild { vec![Example { example: "bytes build 0x[01 02] 0x[03] 0x[04]", description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]", - result: Some(Value::Binary { - val: vec![0x01, 0x02, 0x03, 0x04], - span: Span::test_data(), - }), + result: Some(Value::binary( + vec![0x01, 0x02, 0x03, 0x04], + Span::test_data(), + )), }] } @@ -63,11 +63,7 @@ impl Command for BytesBuild { } } - Ok(Value::Binary { - val: output, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::binary(output, call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/bytes/bytes_.rs b/crates/nu-command/src/bytes/bytes_.rs index 08117e29d..2b64bca9c 100644 --- a/crates/nu-command/src/bytes/bytes_.rs +++ b/crates/nu-command/src/bytes/bytes_.rs @@ -34,16 +34,16 @@ impl Command for Bytes { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Bytes.signature(), &Bytes.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/bytes/collect.rs b/crates/nu-command/src/bytes/collect.rs index 96bfa8328..543c1a927 100644 --- a/crates/nu-command/src/bytes/collect.rs +++ b/crates/nu-command/src/bytes/collect.rs @@ -68,28 +68,16 @@ impl Command for BytesCollect { } match separator { - None => Ok(Value::Binary { - val: output_binary, - span: call.head, - } - .into_pipeline_data()), + None => Ok(Value::binary(output_binary, call.head).into_pipeline_data()), Some(sep) => { if output_binary.is_empty() { - Ok(Value::Binary { - val: output_binary, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::binary(output_binary, call.head).into_pipeline_data()) } else { // have push one extra separator in previous step, pop them out. for _ in sep { let _ = output_binary.pop(); } - Ok(Value::Binary { - val: output_binary, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::binary(output_binary, call.head).into_pipeline_data()) } } } @@ -100,18 +88,15 @@ impl Command for BytesCollect { Example { description: "Create a byte array from input", example: "[0x[11] 0x[13 15]] | bytes collect", - result: Some(Value::Binary { - val: vec![0x11, 0x13, 0x15], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x11, 0x13, 0x15], Span::test_data())), }, Example { description: "Create a byte array from input with a separator", example: "[0x[11] 0x[33] 0x[44]] | bytes collect 0x[01]", - result: Some(Value::Binary { - val: vec![0x11, 0x01, 0x33, 0x01, 0x44], - span: Span::test_data(), - }), + result: Some(Value::binary( + vec![0x11, 0x01, 0x33, 0x01, 0x44], + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/bytes/ends_with.rs b/crates/nu-command/src/bytes/ends_with.rs index 1c18b2558..6748a89c8 100644 --- a/crates/nu-command/src/bytes/ends_with.rs +++ b/crates/nu-command/src/bytes/ends_with.rs @@ -89,22 +89,20 @@ impl Command for BytesEndsWith { } fn ends_with(val: &Value, args: &Arguments, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => Value::bool(val.ends_with(&args.pattern), *val_span), + Value::Binary { val, .. } => Value::bool(val.ends_with(&args.pattern), val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/bytes/index_of.rs b/crates/nu-command/src/bytes/index_of.rs index 6a5ac0fdc..1b1101daf 100644 --- a/crates/nu-command/src/bytes/index_of.rs +++ b/crates/nu-command/src/bytes/index_of.rs @@ -95,58 +95,53 @@ impl Command for BytesIndexOf { Example { description: "Returns all matched index", example: " 0x[33 44 55 10 01 33 44 33 44] | bytes index-of -a 0x[33 44]", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(5), Value::test_int(7)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(5), Value::test_int(7)], + Span::test_data(), + )), }, Example { description: "Returns all matched index, searching from end", example: " 0x[33 44 55 10 01 33 44 33 44] | bytes index-of -a -e 0x[33 44]", - result: Some(Value::List { - vals: vec![Value::test_int(7), Value::test_int(5), Value::test_int(0)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(7), Value::test_int(5), Value::test_int(0)], + Span::test_data(), + )), }, Example { description: "Returns index of pattern for specific column", example: r#" [[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes index-of 0x[11] ColA ColC"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string(), "ColC".to_string()], vals: vec![ Value::test_int(0), - Value::Binary { - val: vec![0x14, 0x15, 0x16], - span: Span::test_data(), - }, + Value::binary(vec![0x14, 0x15, 0x16], Span::test_data()), Value::test_int(-1), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } } fn index_of(val: &Value, args: &Arguments, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => index_of_impl(val, args, *val_span), + Value::Binary { val, .. } => index_of_impl(val, args, val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } @@ -157,22 +152,20 @@ fn index_of_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { let mut iter = input.windows(arg.pattern.len()); if arg.end { - Value::Int { - val: iter - .rev() + Value::int( + iter.rev() .position(|sub_bytes| sub_bytes == arg.pattern) .map(|x| (input.len() - arg.pattern.len() - x) as i64) .unwrap_or(-1), span, - } + ) } else { - Value::Int { - val: iter - .position(|sub_bytes| sub_bytes == arg.pattern) + Value::int( + iter.position(|sub_bytes| sub_bytes == arg.pattern) .map(|x| x as i64) .unwrap_or(-1), span, - } + ) } } } @@ -186,10 +179,7 @@ fn search_all_index(input: &[u8], pattern: &[u8], from_end: bool, span: Span) -> ); while left >= 0 { if &input[left as usize..right as usize] == pattern { - result.push(Value::Int { - val: left as i64, - span, - }); + result.push(Value::int(left as i64, span)); left -= pattern.len() as isize; right -= pattern.len() as isize; } else { @@ -197,7 +187,7 @@ fn search_all_index(input: &[u8], pattern: &[u8], from_end: bool, span: Span) -> right -= 1; } } - Value::List { vals: result, span } + Value::list(result, span) } else { // doing find stuff. let (mut left, mut right) = (0, pattern.len()); @@ -205,10 +195,7 @@ fn search_all_index(input: &[u8], pattern: &[u8], from_end: bool, span: Span) -> let pattern_len = pattern.len(); while right <= input_len { if &input[left..right] == pattern { - result.push(Value::Int { - val: left as i64, - span, - }); + result.push(Value::int(left as i64, span)); left += pattern_len; right += pattern_len; } else { @@ -217,7 +204,7 @@ fn search_all_index(input: &[u8], pattern: &[u8], from_end: bool, span: Span) -> } } - Value::List { vals: result, span } + Value::list(result, span) } } diff --git a/crates/nu-command/src/bytes/length.rs b/crates/nu-command/src/bytes/length.rs index 115354788..a21f78ea9 100644 --- a/crates/nu-command/src/bytes/length.rs +++ b/crates/nu-command/src/bytes/length.rs @@ -64,32 +64,30 @@ impl Command for BytesLen { Example { description: "Return the lengths of multiple binaries", example: "[0x[1F FF AA AB] 0x[1F]] | bytes length", - result: Some(Value::List { - vals: vec![Value::test_int(4), Value::test_int(1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(4), Value::test_int(1)], + Span::test_data(), + )), }, ] } } fn length(val: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => Value::int(val.len() as i64, *val_span), + Value::Binary { val, .. } => Value::int(val.len() as i64, val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/bytes/remove.rs b/crates/nu-command/src/bytes/remove.rs index a0dd3a04e..28b22816e 100644 --- a/crates/nu-command/src/bytes/remove.rs +++ b/crates/nu-command/src/bytes/remove.rs @@ -87,10 +87,10 @@ impl Command for BytesRemove { Example { description: "Remove contents", example: "0x[10 AA FF AA FF] | bytes remove 0x[10 AA]", - result: Some(Value::Binary { - val: vec![0xFF, 0xAA, 0xFF], - span: Span::test_data(), - }), + result: Some(Value::binary ( + vec![0xFF, 0xAA, 0xFF], + Span::test_data(), + )), }, Example { description: "Remove all occurrences of find binary in record field", @@ -103,56 +103,54 @@ impl Command for BytesRemove { Example { description: "Remove occurrences of find binary from end", example: "0x[10 AA 10 BB CC AA 10] | bytes remove -e 0x[10]", - result: Some(Value::Binary { - val: vec![0x10, 0xAA, 0x10, 0xBB, 0xCC, 0xAA], - span: Span::test_data(), - }), + result: Some(Value::binary ( + vec![0x10, 0xAA, 0x10, 0xBB, 0xCC, 0xAA], + Span::test_data(), + )), }, Example { description: "Remove all occurrences of find binary in table", example: "[[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes remove 0x[11] ColA ColC", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string(), "ColC".to_string()], vals: vec![ - Value::Binary { - val: vec![0x12, 0x13], - span: Span::test_data(), - }, - Value::Binary { - val: vec![0x14, 0x15, 0x16], - span: Span::test_data(), - }, - Value::Binary { - val: vec![0x17, 0x18, 0x19], - span: Span::test_data(), - }, + Value::binary ( + vec![0x12, 0x13], + Span::test_data(), + ), + Value::binary ( + vec![0x14, 0x15, 0x16], + Span::test_data(), + ), + Value::binary ( + vec![0x17, 0x18, 0x19], + Span::test_data(), + ), ] })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } } fn remove(val: &Value, args: &Arguments, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => remove_impl(val, args, *val_span), + Value::Binary { val, .. } => remove_impl(val, args, val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } @@ -180,7 +178,7 @@ fn remove_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { let mut remain = input[..left as usize].iter().copied().rev().collect(); result.append(&mut remain); result = result.into_iter().rev().collect(); - Value::Binary { val: result, span } + Value::binary(result, span) } else { let (mut left, mut right) = (0, arg.pattern.len()); while right <= input_len { @@ -200,7 +198,7 @@ fn remove_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { // we have something to remove and remove_all is False. let mut remain = input[left..].to_vec(); result.append(&mut remain); - Value::Binary { val: result, span } + Value::binary(result, span) } } diff --git a/crates/nu-command/src/bytes/replace.rs b/crates/nu-command/src/bytes/replace.rs index 5fdc61314..b811a20a1 100644 --- a/crates/nu-command/src/bytes/replace.rs +++ b/crates/nu-command/src/bytes/replace.rs @@ -87,64 +87,62 @@ impl Command for BytesReplace { Example { description: "Find and replace contents", example: "0x[10 AA FF AA FF] | bytes replace 0x[10 AA] 0x[FF]", - result: Some(Value::Binary { - val: vec![0xFF, 0xFF, 0xAA, 0xFF], - span: Span::test_data(), - }), + result: Some(Value::binary ( + vec![0xFF, 0xFF, 0xAA, 0xFF], + Span::test_data(), + )), }, Example { description: "Find and replace all occurrences of find binary", example: "0x[10 AA 10 BB 10] | bytes replace -a 0x[10] 0x[A0]", - result: Some(Value::Binary { - val: vec![0xA0, 0xAA, 0xA0, 0xBB, 0xA0], - span: Span::test_data(), - }), + result: Some(Value::binary ( + vec![0xA0, 0xAA, 0xA0, 0xBB, 0xA0], + Span::test_data(), + )), }, Example { description: "Find and replace all occurrences of find binary in table", example: "[[ColA ColB ColC]; [0x[11 12 13] 0x[14 15 16] 0x[17 18 19]]] | bytes replace -a 0x[11] 0x[13] ColA ColC", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string(), "ColC".to_string()], vals: vec![ - Value::Binary { - val: vec![0x13, 0x12, 0x13], - span: Span::test_data(), - }, - Value::Binary { - val: vec![0x14, 0x15, 0x16], - span: Span::test_data(), - }, - Value::Binary { - val: vec![0x17, 0x18, 0x19], - span: Span::test_data(), - }, + Value::binary ( + vec![0x13, 0x12, 0x13], + Span::test_data(), + ), + Value::binary ( + vec![0x14, 0x15, 0x16], + Span::test_data(), + ), + Value::binary ( + vec![0x17, 0x18, 0x19], + Span::test_data(), + ), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } } fn replace(val: &Value, args: &Arguments, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => replace_impl(val, args, *val_span), + Value::Binary { val, .. } => replace_impl(val, args, val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } @@ -174,10 +172,7 @@ fn replace_impl(input: &[u8], arg: &Arguments, span: Span) -> Value { let mut remain = input[left..].to_vec(); replaced.append(&mut remain); - Value::Binary { - val: replaced, - span, - } + Value::binary(replaced, span) } #[cfg(test)] diff --git a/crates/nu-command/src/bytes/reverse.rs b/crates/nu-command/src/bytes/reverse.rs index 97488f937..8433a3dd0 100644 --- a/crates/nu-command/src/bytes/reverse.rs +++ b/crates/nu-command/src/bytes/reverse.rs @@ -56,47 +56,39 @@ impl Command for BytesReverse { Example { description: "Reverse bytes `0x[1F FF AA AA]`", example: "0x[1F FF AA AA] | bytes reverse", - result: Some(Value::Binary { - val: vec![0xAA, 0xAA, 0xFF, 0x1F], - span: Span::test_data(), - }), + result: Some(Value::binary( + vec![0xAA, 0xAA, 0xFF, 0x1F], + Span::test_data(), + )), }, Example { description: "Reverse bytes `0x[FF AA AA]`", example: "0x[FF AA AA] | bytes reverse", - result: Some(Value::Binary { - val: vec![0xAA, 0xAA, 0xFF], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0xAA, 0xAA, 0xFF], Span::test_data())), }, ] } } fn reverse(val: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => { + Value::Binary { val, .. } => { let mut reversed_input = val.to_vec(); reversed_input.reverse(); - Value::Binary { - val: reversed_input, - span: *val_span, - } + Value::binary(reversed_input, val_span) } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/bytes/starts_with.rs b/crates/nu-command/src/bytes/starts_with.rs index e1d7c8a52..8701b7852 100644 --- a/crates/nu-command/src/bytes/starts_with.rs +++ b/crates/nu-command/src/bytes/starts_with.rs @@ -84,15 +84,15 @@ impl Command for BytesStartsWith { Ok(v @ Value::Error { .. }) => return Ok(v.clone().into_pipeline_data()), // Unsupported data Ok(other) => { - return Ok(Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + return Ok(Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string and binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - } + ) .into_pipeline_data()); } Err(err) => return Err(err.to_owned()), @@ -147,22 +147,20 @@ impl Command for BytesStartsWith { } fn starts_with(val: &Value, args: &Arguments, span: Span) -> Value { + let val_span = val.span(); match val { - Value::Binary { - val, - span: val_span, - } => Value::bool(val.starts_with(&args.pattern), *val_span), + Value::Binary { val, .. } => Value::bool(val.starts_with(&args.pattern), val_span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => val.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/charting/hashable_value.rs b/crates/nu-command/src/charting/hashable_value.rs index 49074e122..1e7ff8b37 100644 --- a/crates/nu-command/src/charting/hashable_value.rs +++ b/crates/nu-command/src/charting/hashable_value.rs @@ -65,18 +65,40 @@ impl HashableValue { /// /// If the given value is not hashable(mainly because of it is structured data), an error will returned. pub fn from_value(value: Value, span: Span) -> Result { + let val_span = value.span(); match value { - Value::Bool { val, span } => Ok(HashableValue::Bool { val, span }), - Value::Int { val, span } => Ok(HashableValue::Int { val, span }), - Value::Filesize { val, span } => Ok(HashableValue::Filesize { val, span }), - Value::Duration { val, span } => Ok(HashableValue::Duration { val, span }), - Value::Date { val, span } => Ok(HashableValue::Date { val, span }), - Value::Float { val, span } => Ok(HashableValue::Float { - val: val.to_ne_bytes(), - span, + Value::Bool { val, .. } => Ok(HashableValue::Bool { + val, + span: val_span, + }), + Value::Int { val, .. } => Ok(HashableValue::Int { + val, + span: val_span, + }), + Value::Filesize { val, .. } => Ok(HashableValue::Filesize { + val, + span: val_span, + }), + Value::Duration { val, .. } => Ok(HashableValue::Duration { + val, + span: val_span, + }), + Value::Date { val, .. } => Ok(HashableValue::Date { + val, + span: val_span, + }), + Value::Float { val, .. } => Ok(HashableValue::Float { + val: val.to_ne_bytes(), + span: val_span, + }), + Value::String { val, .. } => Ok(HashableValue::String { + val, + span: val_span, + }), + Value::Binary { val, .. } => Ok(HashableValue::Binary { + val, + span: val_span, }), - Value::String { val, span } => Ok(HashableValue::String { val, span }), - Value::Binary { val, span } => Ok(HashableValue::Binary { val, span }), // Explicitly propagate errors instead of dropping them. Value::Error { error, .. } => Err(*error), @@ -92,17 +114,14 @@ impl HashableValue { /// Convert from self to nu's core data type `Value`. pub fn into_value(self) -> Value { match self { - HashableValue::Bool { val, span } => Value::Bool { val, span }, - HashableValue::Int { val, span } => Value::Int { val, span }, - HashableValue::Filesize { val, span } => Value::Filesize { val, span }, - HashableValue::Duration { val, span } => Value::Duration { val, span }, - HashableValue::Date { val, span } => Value::Date { val, span }, - HashableValue::Float { val, span } => Value::Float { - val: f64::from_ne_bytes(val), - span, - }, - HashableValue::String { val, span } => Value::String { val, span }, - HashableValue::Binary { val, span } => Value::Binary { val, span }, + HashableValue::Bool { val, span } => Value::bool(val, span), + HashableValue::Int { val, span } => Value::int(val, span), + HashableValue::Filesize { val, span } => Value::filesize(val, span), + HashableValue::Duration { val, span } => Value::duration(val, span), + HashableValue::Date { val, span } => Value::date(val, span), + HashableValue::Float { val, span } => Value::float(f64::from_ne_bytes(val), span), + HashableValue::String { val, span } => Value::string(val, span), + HashableValue::Binary { val, span } => Value::binary(val, span), } } } @@ -167,29 +186,24 @@ mod test { let span = Span::test_data(); let values = vec![ ( - Value::Bool { val: true, span }, + Value::bool(true, span), HashableValue::Bool { val: true, span }, ), + (Value::int(1, span), HashableValue::Int { val: 1, span }), ( - Value::Int { val: 1, span }, - HashableValue::Int { val: 1, span }, - ), - ( - Value::Filesize { val: 1, span }, + Value::filesize(1, span), HashableValue::Filesize { val: 1, span }, ), ( - Value::Duration { val: 1, span }, + Value::duration(1, span), HashableValue::Duration { val: 1, span }, ), ( - Value::Date { - val: DateTime::::parse_from_rfc2822( - "Wed, 18 Feb 2015 23:16:09 GMT", - ) - .unwrap(), + Value::date( + DateTime::::parse_from_rfc2822("Wed, 18 Feb 2015 23:16:09 GMT") + .unwrap(), span, - }, + ), HashableValue::Date { val: DateTime::::parse_from_rfc2822( "Wed, 18 Feb 2015 23:16:09 GMT", @@ -199,17 +213,14 @@ mod test { }, ), ( - Value::String { - val: "1".to_string(), - span, - }, + Value::string("1".to_string(), span), HashableValue::String { val: "1".to_string(), span, }, ), ( - Value::Binary { val: vec![1], span }, + Value::binary(vec![1], span), HashableValue::Binary { val: vec![1], span }, ), ]; @@ -225,22 +236,12 @@ mod test { fn from_unhashable_value() { let span = Span::test_data(); let values = [ - Value::List { - vals: vec![Value::Bool { val: true, span }], - span, - }, - Value::Closure { - val: 0, - captures: HashMap::new(), - span, - }, - Value::Nothing { span }, - Value::Error { - error: Box::new(ShellError::DidYouMean("what?".to_string(), span)), - span, - }, - Value::CellPath { - val: CellPath { + Value::list(vec![Value::bool(true, span)], span), + Value::closure(0, HashMap::new(), span), + Value::nothing(span), + Value::error(ShellError::DidYouMean("what?".to_string(), span), span), + Value::cell_path( + CellPath { members: vec![PathMember::Int { val: 0, span, @@ -248,7 +249,7 @@ mod test { }], }, span, - }, + ), ]; for v in values { assert!(HashableValue::from_value(v, Span::unknown()).is_err()) @@ -259,15 +260,12 @@ mod test { fn from_to_tobe_same() { let span = Span::test_data(); let values = vec![ - Value::Bool { val: true, span }, - Value::Int { val: 1, span }, - Value::Filesize { val: 1, span }, - Value::Duration { val: 1, span }, - Value::String { - val: "1".to_string(), - span, - }, - Value::Binary { val: vec![1], span }, + Value::bool(true, span), + Value::int(1, span), + Value::filesize(1, span), + Value::duration(1, span), + Value::string("1".to_string(), span), + Value::binary(vec![1], span), ]; for val in values.into_iter() { let expected_val = val.clone(); diff --git a/crates/nu-command/src/charting/histogram.rs b/crates/nu-command/src/charting/histogram.rs index 5bbb4413e..53a6f998c 100755 --- a/crates/nu-command/src/charting/histogram.rs +++ b/crates/nu-command/src/charting/histogram.rs @@ -51,8 +51,8 @@ impl Command for Histogram { Example { description: "Compute a histogram for a list of numbers", example: "[1 2 1] | histogram", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["value".to_string(), "count".to_string(), "quantile".to_string(), "percentage".to_string(), "frequency".to_string()], vals: vec![ Value::test_int(1), @@ -72,8 +72,8 @@ impl Command for Histogram { Value::test_string("*********************************"), ], })], - span: Span::test_data(), - } + Span::test_data(), + ) ), }, Example { @@ -274,16 +274,10 @@ fn histogram_impl( cols: result_cols.clone(), vals: vec![ val.into_value(), - Value::Int { val: count, span }, - Value::Float { - val: quantile, - span, - }, - Value::String { - val: percentage, - span, - }, - Value::String { val: freq, span }, + Value::int(count, span), + Value::float(quantile, span), + Value::string(percentage, span), + Value::string(freq, span), ], }, span, @@ -291,11 +285,7 @@ fn histogram_impl( )); } result.sort_by(|a, b| b.0.cmp(&a.0)); - Value::List { - vals: result.into_iter().map(|x| x.1).collect(), - span, - } - .into_pipeline_data() + Value::list(result.into_iter().map(|x| x.1).collect(), span).into_pipeline_data() } #[cfg(test)] diff --git a/crates/nu-command/src/conversions/fill.rs b/crates/nu-command/src/conversions/fill.rs index 01697e6ea..d772fb653 100644 --- a/crates/nu-command/src/conversions/fill.rs +++ b/crates/nu-command/src/conversions/fill.rs @@ -86,53 +86,35 @@ impl Command for Fill { description: "Fill a string on the left side to a width of 15 with the character '─'", example: "'nushell' | fill -a l -c '─' -w 15", - result: Some(Value::String { - val: "nushell────────".into(), - span: Span::test_data(), - }), + result: Some(Value::string("nushell────────", Span::test_data())), }, Example { description: "Fill a string on the right side to a width of 15 with the character '─'", example: "'nushell' | fill -a r -c '─' -w 15", - result: Some(Value::String { - val: "────────nushell".into(), - span: Span::test_data(), - }), + result: Some(Value::string("────────nushell", Span::test_data())), }, Example { description: "Fill a string on both sides to a width of 15 with the character '─'", example: "'nushell' | fill -a m -c '─' -w 15", - result: Some(Value::String { - val: "────nushell────".into(), - span: Span::test_data(), - }), + result: Some(Value::string("────nushell────", Span::test_data())), }, Example { description: "Fill a number on the left side to a width of 5 with the character '0'", example: "1 | fill --alignment right --character '0' --width 5", - result: Some(Value::String { - val: "00001".into(), - span: Span::test_data(), - }), + result: Some(Value::string("00001", Span::test_data())), }, Example { description: "Fill a number on both sides to a width of 5 with the character '0'", example: "1.1 | fill --alignment center --character '0' --width 5", - result: Some(Value::String { - val: "01.10".into(), - span: Span::test_data(), - }), + result: Some(Value::string("01.10", Span::test_data())), }, Example { description: "Fill a filesize on the left side to a width of 5 with the character '0'", example: "1kib | fill --alignment middle --character '0' --width 10", - result: Some(Value::String { - val: "0001024000".into(), - span: Span::test_data(), - }), + result: Some(Value::string("0001024000", Span::test_data())), }, ] } @@ -198,15 +180,15 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::String { val, .. } => fill_string(val, args, span), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "int, filesize, float, string".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } @@ -214,18 +196,18 @@ fn fill_float(num: f64, args: &Arguments, span: Span) -> Value { let s = num.to_string(); let out_str = pad(&s, args.width, &args.character, args.alignment, false); - Value::String { val: out_str, span } + Value::string(out_str, span) } fn fill_int(num: i64, args: &Arguments, span: Span) -> Value { let s = num.to_string(); let out_str = pad(&s, args.width, &args.character, args.alignment, false); - Value::String { val: out_str, span } + Value::string(out_str, span) } fn fill_string(s: &str, args: &Arguments, span: Span) -> Value { let out_str = pad(s, args.width, &args.character, args.alignment, false); - Value::String { val: out_str, span } + Value::string(out_str, span) } fn pad(s: &str, width: usize, pad_char: &str, alignment: FillAlignment, truncate: bool) -> String { diff --git a/crates/nu-command/src/conversions/into/binary.rs b/crates/nu-command/src/conversions/into/binary.rs index f2b6e632d..e64905a39 100644 --- a/crates/nu-command/src/conversions/into/binary.rs +++ b/crates/nu-command/src/conversions/into/binary.rs @@ -72,29 +72,29 @@ impl Command for SubCommand { Example { description: "convert string to a nushell binary primitive", example: "'This is a string that is exactly 52 characters long.' | into binary", - result: Some(Value::Binary { - val: "This is a string that is exactly 52 characters long." + result: Some(Value::binary( + "This is a string that is exactly 52 characters long." .to_string() .as_bytes() .to_vec(), - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "convert a number to a nushell binary primitive", example: "1 | into binary", - result: Some(Value::Binary { - val: i64::from(1).to_ne_bytes().to_vec(), - span: Span::test_data(), - }), + result: Some(Value::binary( + i64::from(1).to_ne_bytes().to_vec(), + Span::test_data(), + )), }, Example { description: "convert a boolean to a nushell binary primitive", example: "true | into binary", - result: Some(Value::Binary { - val: i64::from(1).to_ne_bytes().to_vec(), - span: Span::test_data(), - }), + result: Some(Value::binary( + i64::from(1).to_ne_bytes().to_vec(), + Span::test_data(), + )), }, Example { description: "convert a filesize to a nushell binary primitive", @@ -109,19 +109,16 @@ impl Command for SubCommand { Example { description: "convert a decimal to a nushell binary primitive", example: "1.234 | into binary", - result: Some(Value::Binary { - val: 1.234f64.to_ne_bytes().to_vec(), - span: Span::test_data(), - }), + result: Some(Value::binary( + 1.234f64.to_ne_bytes().to_vec(), + Span::test_data(), + )), }, Example { description: "convert an integer to a nushell binary primitive with compact enabled", example: "10 | into binary --compact", - result: Some(Value::Binary { - val: vec![10], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![10], Span::test_data())), }, ] } @@ -138,22 +135,16 @@ fn into_binary( let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths); match input { - PipelineData::ExternalStream { stdout: None, .. } => Ok(Value::Binary { - val: vec![], - span: head, + PipelineData::ExternalStream { stdout: None, .. } => { + Ok(Value::binary(vec![], head).into_pipeline_data()) } - .into_pipeline_data()), PipelineData::ExternalStream { stdout: Some(stream), .. } => { // TODO: in the future, we may want this to stream out, converting each to bytes let output = stream.into_bytes()?; - Ok(Value::Binary { - val: output.item, - span: head, - } - .into_pipeline_data()) + Ok(Value::binary(output.item, head).into_pipeline_data()) } _ => { let args = Arguments { @@ -168,50 +159,32 @@ fn into_binary( pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value { let value = match input { Value::Binary { .. } => input.clone(), - Value::Int { val, .. } => Value::Binary { - val: val.to_ne_bytes().to_vec(), - span, - }, - Value::Float { val, .. } => Value::Binary { - val: val.to_ne_bytes().to_vec(), - span, - }, - Value::Filesize { val, .. } => Value::Binary { - val: val.to_ne_bytes().to_vec(), - span, - }, - Value::String { val, .. } => Value::Binary { - val: val.as_bytes().to_vec(), - span, - }, - Value::Bool { val, .. } => Value::Binary { - val: i64::from(*val).to_ne_bytes().to_vec(), - span, - }, - Value::Duration { val, .. } => Value::Binary { - val: val.to_ne_bytes().to_vec(), - span, - }, - Value::Date { val, .. } => Value::Binary { - val: val.format("%c").to_string().as_bytes().to_vec(), - span, - }, + Value::Int { val, .. } => Value::binary(val.to_ne_bytes().to_vec(), span), + Value::Float { val, .. } => Value::binary(val.to_ne_bytes().to_vec(), span), + Value::Filesize { val, .. } => Value::binary(val.to_ne_bytes().to_vec(), span), + Value::String { val, .. } => Value::binary(val.as_bytes().to_vec(), span), + Value::Bool { val, .. } => Value::binary(i64::from(*val).to_ne_bytes().to_vec(), span), + Value::Duration { val, .. } => Value::binary(val.to_ne_bytes().to_vec(), span), + Value::Date { val, .. } => { + Value::binary(val.format("%c").to_string().as_bytes().to_vec(), span) + } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer, float, filesize, string, date, duration, binary or bool" .into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), }; if _args.compact { - if let Value::Binary { val, span } = value { + let val_span = value.span(); + if let Value::Binary { val, .. } = value { let val = if cfg!(target_endian = "little") { match val.iter().rposition(|&x| x != 0) { Some(idx) => &val[..idx + 1], @@ -224,10 +197,7 @@ pub fn action(input: &Value, _args: &Arguments, span: Span) -> Value { } }; - Value::Binary { - val: val.to_vec(), - span, - } + Value::binary(val.to_vec(), val_span) } else { value } diff --git a/crates/nu-command/src/conversions/into/bool.rs b/crates/nu-command/src/conversions/into/bool.rs index c5b81e4ed..fbbad6768 100644 --- a/crates/nu-command/src/conversions/into/bool.rs +++ b/crates/nu-command/src/conversions/into/bool.rs @@ -58,8 +58,8 @@ impl Command for SubCommand { Example { description: "Convert value to boolean in table", example: "[[value]; ['false'] ['1'] [0] [1.0] [true]] | into bool value", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["value".to_string()], vals: vec![Value::bool(false, span)], @@ -82,7 +82,7 @@ impl Command for SubCommand { }), ], span, - }), + )), }, Example { description: "Convert bool to boolean", @@ -149,32 +149,23 @@ fn string_to_boolean(s: &str, span: Span) -> Result { fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { match input { Value::Bool { .. } => input.clone(), - Value::Int { val, .. } => Value::Bool { - val: *val != 0, - span, - }, - Value::Float { val, .. } => Value::Bool { - val: val.abs() >= f64::EPSILON, - span, - }, + Value::Int { val, .. } => Value::bool(*val != 0, span), + Value::Float { val, .. } => Value::bool(val.abs() >= f64::EPSILON, span), Value::String { val, .. } => match string_to_boolean(val, span) { - Ok(val) => Value::Bool { val, span }, - Err(error) => Value::Error { - error: Box::new(error), - span, - }, + Ok(val) => Value::bool(val, span), + Err(error) => Value::error(error, span), }, // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "bool, integer, float or string".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/conversions/into/command.rs b/crates/nu-command/src/conversions/into/command.rs index 97b35fe24..1b59793ed 100644 --- a/crates/nu-command/src/conversions/into/command.rs +++ b/crates/nu-command/src/conversions/into/command.rs @@ -34,16 +34,16 @@ impl Command for Into { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Into.signature(), &[], engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/conversions/into/datetime.rs b/crates/nu-command/src/conversions/into/datetime.rs index b03bfe4a2..8dd250643 100644 --- a/crates/nu-command/src/conversions/into/datetime.rs +++ b/crates/nu-command/src/conversions/into/datetime.rs @@ -154,10 +154,10 @@ impl Command for SubCommand { fn examples(&self) -> Vec { let example_result_1 = |nanos: i64| { - Some(Value::Date { - val: Utc.timestamp_nanos(nanos).into(), - span: Span::test_data(), - }) + Some(Value::date( + Utc.timestamp_nanos(nanos).into(), + Span::test_data(), + )) }; vec![ Example { @@ -195,35 +195,35 @@ impl Command for SubCommand { Example { description: "Convert list of timestamps to datetimes", example: r#"["2023-03-30 10:10:07 -05:00", "2023-05-05 13:43:49 -05:00", "2023-06-05 01:37:42 -05:00"] | into datetime"#, - result: Some(Value::List { - vals: vec![ - Value::Date { - val: DateTime::parse_from_str( + result: Some(Value::list( + vec![ + Value::date( + DateTime::parse_from_str( "2023-03-30 10:10:07 -05:00", "%Y-%m-%d %H:%M:%S %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, - Value::Date { - val: DateTime::parse_from_str( + Span::test_data(), + ), + Value::date( + DateTime::parse_from_str( "2023-05-05 13:43:49 -05:00", "%Y-%m-%d %H:%M:%S %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, - Value::Date { - val: DateTime::parse_from_str( + Span::test_data(), + ), + Value::date( + DateTime::parse_from_str( "2023-06-05 01:37:42 -05:00", "%Y-%m-%d %H:%M:%S %z", ) .expect("date calculation should not fail in test"), - span: Span::test_data(), - }, + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -240,12 +240,7 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { if matches!(input, Value::String { .. }) && dateformat.is_none() { if let Ok(input_val) = input.as_spanned_string() { match parse_date_from_string(&input_val.item, input_val.span) { - Ok(date) => { - return Value::Date { - val: date, - span: input_val.span, - } - } + Ok(date) => return Value::date(date, input_val.span), Err(err) => err, }; } @@ -259,15 +254,15 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => return input.clone(), other => { - return Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + return Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string and integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }; + }, + head, + ); } }; @@ -277,107 +272,87 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { // note all these `.timestamp_nanos()` could overflow if we didn't check range in ` | into int`. // default to UTC - None => Value::Date { - val: Utc.timestamp_nanos(ts).into(), - span: head, - }, + None => Value::date(Utc.timestamp_nanos(ts).into(), head), Some(Spanned { item, span }) => match item { Zone::Utc => { let dt = Utc.timestamp_nanos(ts); - Value::Date { - val: dt.into(), - span: *span, - } + Value::date(dt.into(), *span) } Zone::Local => { let dt = Local.timestamp_nanos(ts); - Value::Date { - val: dt.into(), - span: *span, - } + Value::date(dt.into(), *span) } Zone::East(i) => match FixedOffset::east_opt((*i as i32) * HOUR) { Some(eastoffset) => { let dt = eastoffset.timestamp_nanos(ts); - Value::Date { - val: dt, - span: *span, - } + Value::date(dt, *span) } - None => Value::Error { - error: Box::new(ShellError::DatetimeParseError( - input.debug_value(), - *span, - )), - span: *span, - }, + None => Value::error( + ShellError::DatetimeParseError(input.debug_value(), *span), + *span, + ), }, Zone::West(i) => match FixedOffset::west_opt((*i as i32) * HOUR) { Some(westoffset) => { let dt = westoffset.timestamp_nanos(ts); - Value::Date { - val: dt, - span: *span, - } + Value::date(dt, *span) } - None => Value::Error { - error: Box::new(ShellError::DatetimeParseError( - input.debug_value(), - *span, - )), - span: *span, - }, + None => Value::error( + ShellError::DatetimeParseError(input.debug_value(), *span), + *span, + ), }, - Zone::Error => Value::Error { + Zone::Error => Value::error( // This is an argument error, not an input error - error: Box::new(ShellError::TypeMismatch { + ShellError::TypeMismatch { err_message: "Invalid timezone or offset".to_string(), span: *span, - }), - span: *span, - }, + }, + *span, + ), }, }; }; } // If input is not a timestamp, try parsing it as a string + let span = input.span(); match input { - Value::String { val, span } => { + Value::String { val, .. } => { match dateformat { Some(dt) => match DateTime::parse_from_str(val, &dt.0) { - Ok(d) => Value::Date { val: d, span: head }, + Ok(d) => Value::date ( d, head ), Err(reason) => { - Value::Error { - error: Box::new(ShellError::CantConvert { to_type: format!("could not parse as datetime using format '{}'", dt.0), from_type: reason.to_string(), span: head, help: Some("you can use `into datetime` without a format string to enable flexible parsing".to_string()) }), - span: head, - } + Value::error ( + ShellError::CantConvert { to_type: format!("could not parse as datetime using format '{}'", dt.0), from_type: reason.to_string(), span: head, help: Some("you can use `into datetime` without a format string to enable flexible parsing".to_string()) }, + head, + ) } }, // Tries to automatically parse the date // (i.e. without a format string) // and assumes the system's local timezone if none is specified - None => match parse_date_from_string(val, *span) { - Ok(date) => Value::Date { - val: date, - span: *span, - }, + None => match parse_date_from_string(val, span) { + Ok(date) => Value::date ( + date, + span, + ), Err(err) => err, }, } } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } @@ -404,11 +379,10 @@ mod tests { cell_paths: None, }; let actual = action(&date_str, &args, Span::test_data()); - let expected = Value::Date { - val: DateTime::parse_from_str("16.11.1984 8:00 am +0000", "%d.%m.%Y %H:%M %P %z") - .unwrap(), - span: Span::test_data(), - }; + let expected = Value::date( + DateTime::parse_from_str("16.11.1984 8:00 am +0000", "%d.%m.%Y %H:%M %P %z").unwrap(), + Span::test_data(), + ); assert_eq!(actual, expected) } @@ -421,11 +395,10 @@ mod tests { cell_paths: None, }; let actual = action(&date_str, &args, Span::test_data()); - let expected = Value::Date { - val: DateTime::parse_from_str("2020-08-04T16:39:18+00:00", "%Y-%m-%dT%H:%M:%S%z") - .unwrap(), - span: Span::test_data(), - }; + let expected = Value::date( + DateTime::parse_from_str("2020-08-04T16:39:18+00:00", "%Y-%m-%dT%H:%M:%S%z").unwrap(), + Span::test_data(), + ); assert_eq!(actual, expected) } @@ -442,11 +415,10 @@ mod tests { cell_paths: None, }; let actual = action(&date_str, &args, Span::test_data()); - let expected = Value::Date { - val: DateTime::parse_from_str("2021-02-27 21:55:40 +08:00", "%Y-%m-%d %H:%M:%S %z") - .unwrap(), - span: Span::test_data(), - }; + let expected = Value::date( + DateTime::parse_from_str("2021-02-27 21:55:40 +08:00", "%Y-%m-%d %H:%M:%S %z").unwrap(), + Span::test_data(), + ); assert_eq!(actual, expected) } @@ -464,11 +436,10 @@ mod tests { cell_paths: None, }; let actual = action(&date_int, &args, Span::test_data()); - let expected = Value::Date { - val: DateTime::parse_from_str("2021-02-27 21:55:40 +08:00", "%Y-%m-%d %H:%M:%S %z") - .unwrap(), - span: Span::test_data(), - }; + let expected = Value::date( + DateTime::parse_from_str("2021-02-27 21:55:40 +08:00", "%Y-%m-%d %H:%M:%S %z").unwrap(), + Span::test_data(), + ); assert_eq!(actual, expected) } @@ -486,10 +457,10 @@ mod tests { cell_paths: None, }; let actual = action(&date_str, &args, Span::test_data()); - let expected = Value::Date { - val: Local.timestamp_opt(1614434140, 0).unwrap().into(), - span: Span::test_data(), - }; + let expected = Value::date( + Local.timestamp_opt(1614434140, 0).unwrap().into(), + Span::test_data(), + ); assert_eq!(actual, expected) } @@ -504,10 +475,10 @@ mod tests { }; let actual = action(&date_str, &args, Span::test_data()); - let expected = Value::Date { - val: Utc.timestamp_opt(1614434140, 0).unwrap().into(), - span: Span::test_data(), - }; + let expected = Value::date( + Utc.timestamp_opt(1614434140, 0).unwrap().into(), + Span::test_data(), + ); assert_eq!(actual, expected) } diff --git a/crates/nu-command/src/conversions/into/decimal.rs b/crates/nu-command/src/conversions/into/decimal.rs index 906669d6c..641eb4963 100644 --- a/crates/nu-command/src/conversions/into/decimal.rs +++ b/crates/nu-command/src/conversions/into/decimal.rs @@ -62,13 +62,13 @@ impl Command for SubCommand { Example { description: "Convert string to decimal in table", example: "[[num]; ['5.01']] | into decimal num", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["num".to_string()], vals: vec![Value::test_float(5.01)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Convert string to decimal", @@ -93,43 +93,44 @@ impl Command for SubCommand { } fn action(input: &Value, _args: &CellPathOnlyArgs, head: Span) -> Value { + let span = input.span(); match input { Value::Float { .. } => input.clone(), - Value::String { val: s, span } => { + Value::String { val: s, .. } => { let other = s.trim(); match other.parse::() { Ok(x) => Value::float(x, head), - Err(reason) => Value::Error { - error: Box::new(ShellError::CantConvert { + Err(reason) => Value::error( + ShellError::CantConvert { to_type: "float".to_string(), from_type: reason.to_string(), - span: *span, + span, help: None, - }), - span: *span, - }, + }, + span, + ), } } - Value::Int { val: v, span } => Value::float(*v as f64, *span), - Value::Bool { val: b, span } => Value::Float { - val: match b { + Value::Int { val: v, .. } => Value::float(*v as f64, span), + Value::Bool { val: b, .. } => Value::float( + match b { true => 1.0, false => 0.0, }, - span: *span, - }, + span, + ), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string, integer or bool".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/conversions/into/duration.rs b/crates/nu-command/src/conversions/into/duration.rs index 667e9d02e..2b1d1bf52 100644 --- a/crates/nu-command/src/conversions/into/duration.rs +++ b/crates/nu-command/src/conversions/into/duration.rs @@ -62,71 +62,50 @@ impl Command for SubCommand { Example { description: "Convert duration string to duration value", example: "'7min' | into duration", - result: Some(Value::Duration { - val: 7 * 60 * NS_PER_SEC, - span, - }), + result: Some(Value::duration(7 * 60 * NS_PER_SEC, span)), }, Example { description: "Convert compound duration string to duration value", example: "'1day 2hr 3min 4sec' | into duration", - result: Some(Value::Duration { - val: (((((/* 1 * */24) + 2) * 60) + 3) * 60 + 4) * NS_PER_SEC, + result: Some(Value::duration( + (((((/* 1 * */24) + 2) * 60) + 3) * 60 + 4) * NS_PER_SEC, span, - }), + )), }, Example { description: "Convert table of duration strings to table of duration values", example: "[[value]; ['1sec'] ['2min'] ['3hr'] ['4day'] ['5wk']] | into duration value", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["value".to_string()], - vals: vec![Value::Duration { - val: NS_PER_SEC, - span, - }], + vals: vec![Value::duration(NS_PER_SEC, span)], }), Value::test_record(Record { cols: vec!["value".to_string()], - vals: vec![Value::Duration { - val: 2 * 60 * NS_PER_SEC, - span, - }], + vals: vec![Value::duration(2 * 60 * NS_PER_SEC, span)], }), Value::test_record(Record { cols: vec!["value".to_string()], - vals: vec![Value::Duration { - val: 3 * 60 * 60 * NS_PER_SEC, - span, - }], + vals: vec![Value::duration(3 * 60 * 60 * NS_PER_SEC, span)], }), Value::test_record(Record { cols: vec!["value".to_string()], - vals: vec![Value::Duration { - val: 4 * 24 * 60 * 60 * NS_PER_SEC, - span, - }], + vals: vec![Value::duration(4 * 24 * 60 * 60 * NS_PER_SEC, span)], }), Value::test_record(Record { cols: vec!["value".to_string()], - vals: vec![Value::Duration { - val: 5 * 7 * 24 * 60 * 60 * NS_PER_SEC, - span, - }], + vals: vec![Value::duration(5 * 7 * 24 * 60 * 60 * NS_PER_SEC, span)], }), ], span, - }), + )), }, Example { description: "Convert duration to duration", example: "420sec | into duration", - result: Some(Value::Duration { - val: 7 * 60 * NS_PER_SEC, - span, - }), + result: Some(Value::duration(7 * 60 * NS_PER_SEC, span)), }, ] } @@ -154,10 +133,7 @@ fn into_duration( let r = ret.update_cell_path(&path.members, Box::new(move |old| action(old, span))); if let Err(error) = r { - return Value::Error { - error: Box::new(error), - span, - }; + return Value::error(error, span); } } @@ -227,29 +203,24 @@ fn string_to_duration(s: &str, span: Span) -> Result { } fn action(input: &Value, span: Span) -> Value { + let value_span = input.span(); match input { Value::Duration { .. } => input.clone(), - Value::String { - val, - span: value_span, - } => match compound_to_duration(val, *value_span) { - Ok(val) => Value::Duration { val, span }, - Err(error) => Value::Error { - error: Box::new(error), - span, - }, + Value::String { val, .. } => match compound_to_duration(val, value_span) { + Ok(val) => Value::duration(val, span), + Err(error) => Value::error(error, span), }, // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string or duration".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/conversions/into/filesize.rs b/crates/nu-command/src/conversions/into/filesize.rs index 6b852c914..3d8bc3510 100644 --- a/crates/nu-command/src/conversions/into/filesize.rs +++ b/crates/nu-command/src/conversions/into/filesize.rs @@ -79,69 +79,45 @@ impl Command for SubCommand { Example { description: "Convert string to filesize in table", example: r#"[[device size]; ["/dev/sda1" "200"] ["/dev/loop0" "50"]] | into filesize size"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["device".to_string(), "size".to_string()], vals: vec![ - Value::String { - val: "/dev/sda1".to_string(), - span: Span::test_data(), - }, - Value::Filesize { - val: 200, - span: Span::test_data(), - }, + Value::string("/dev/sda1".to_string(), Span::test_data()), + Value::filesize(200, Span::test_data()), ], }), Value::test_record(Record { cols: vec!["device".to_string(), "size".to_string()], vals: vec![ - Value::String { - val: "/dev/loop0".to_string(), - span: Span::test_data(), - }, - Value::Filesize { - val: 50, - span: Span::test_data(), - }, + Value::string("/dev/loop0".to_string(), Span::test_data()), + Value::filesize(50, Span::test_data()), ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Convert string to filesize", example: "'2' | into filesize", - result: Some(Value::Filesize { - val: 2, - span: Span::test_data(), - }), + result: Some(Value::filesize(2, Span::test_data())), }, Example { description: "Convert decimal to filesize", example: "8.3 | into filesize", - result: Some(Value::Filesize { - val: 8, - span: Span::test_data(), - }), + result: Some(Value::filesize(8, Span::test_data())), }, Example { description: "Convert int to filesize", example: "5 | into filesize", - result: Some(Value::Filesize { - val: 5, - span: Span::test_data(), - }), + result: Some(Value::filesize(5, Span::test_data())), }, Example { description: "Convert file size to filesize", example: "4KB | into filesize", - result: Some(Value::Filesize { - val: 4000, - span: Span::test_data(), - }), + result: Some(Value::filesize(4000, Span::test_data())), }, ] } @@ -151,37 +127,22 @@ pub fn action(input: &Value, _args: &CellPathOnlyArgs, span: Span) -> Value { let value_span = input.span(); match input { Value::Filesize { .. } => input.clone(), - Value::Int { val, .. } => Value::Filesize { - val: *val, - span: value_span, - }, - Value::Float { val, .. } => Value::Filesize { - val: *val as i64, - span: value_span, - }, + Value::Int { val, .. } => Value::filesize(*val, value_span), + Value::Float { val, .. } => Value::filesize(*val as i64, value_span), Value::String { val, .. } => match int_from_string(val, value_span) { - Ok(val) => Value::Filesize { - val, - span: value_span, - }, - Err(error) => Value::Error { - error: Box::new(error), - span: value_span, - }, + Ok(val) => Value::filesize(val, value_span), + Err(error) => Value::error(error, value_span), }, - Value::Nothing { .. } => Value::Filesize { - val: 0, - span: value_span, - }, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + Value::Nothing { .. } => Value::filesize(0, value_span), + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string and integer".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: value_span, - }), + }, span, - }, + ), } } fn int_from_string(a_string: &str, span: Span) -> Result { diff --git a/crates/nu-command/src/conversions/into/int.rs b/crates/nu-command/src/conversions/into/int.rs index 7a6dfb846..2bb3b5c7b 100644 --- a/crates/nu-command/src/conversions/into/int.rs +++ b/crates/nu-command/src/conversions/into/int.rs @@ -107,33 +107,44 @@ impl Command for SubCommand { let radix = call.get_flag::(engine_state, stack, "radix")?; let radix: u32 = match radix { - Some(Value::Int { val, span }) => { - if !(2..=36).contains(&val) { - return Err(ShellError::TypeMismatch { - err_message: "Radix must lie in the range [2, 36]".to_string(), - span, - }); + Some(val) => { + let span = val.span(); + match val { + Value::Int { val, .. } => { + if !(2..=36).contains(&val) { + return Err(ShellError::TypeMismatch { + err_message: "Radix must lie in the range [2, 36]".to_string(), + span, + }); + } + val as u32 + } + _ => 10, } - val as u32 } - Some(_) => 10, None => 10, }; let endian = call.get_flag::(engine_state, stack, "endian")?; let little_endian = match endian { - Some(Value::String { val, span }) => match val.as_str() { - "native" => cfg!(target_endian = "little"), - "little" => true, - "big" => false, - _ => { - return Err(ShellError::TypeMismatch { - err_message: "Endian must be one of native, little, big".to_string(), - span, - }) + Some(val) => { + let span = val.span(); + match val { + Value::String { val, .. } => match val.as_str() { + "native" => cfg!(target_endian = "little"), + "little" => true, + "big" => false, + _ => { + return Err(ShellError::TypeMismatch { + err_message: "Endian must be one of native, little, big" + .to_string(), + span, + }) + } + }, + _ => false, } - }, - Some(_) => false, + } None => cfg!(target_endian = "little"), }; @@ -175,10 +186,10 @@ impl Command for SubCommand { Example { description: "Convert bool to integer", example: "[false, true] | into int", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(1)], + Span::test_data(), + )), }, Example { description: "Convert date to integer (Unix nanosecond timestamp)", @@ -217,6 +228,7 @@ impl Command for SubCommand { fn action(input: &Value, args: &Arguments, span: Span) -> Value { let radix = args.radix; let little_endian = args.little_endian; + let val_span = input.span(); match input { Value::Int { val: _, .. } => { if radix == 10 { @@ -225,47 +237,35 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { convert_int(input, span, radix) } } - Value::Filesize { val, .. } => Value::Int { val: *val, span }, - Value::Float { val, .. } => Value::Int { - val: { + Value::Filesize { val, .. } => Value::int(*val, span), + Value::Float { val, .. } => Value::int( + { if radix == 10 { *val as i64 } else { - match convert_int( - &Value::Int { - val: *val as i64, - span, - }, - span, - radix, - ) - .as_i64() - { + match convert_int(&Value::int(*val as i64, span), span, radix).as_i64() { Ok(v) => v, _ => { - return Value::Error { - error: Box::new(ShellError::CantConvert { + return Value::error( + ShellError::CantConvert { to_type: "float".to_string(), from_type: "integer".to_string(), span, help: None, - }), + }, span, - } + ) } } } }, span, - }, + ), Value::String { val, .. } => { if radix == 10 { match int_from_string(val, span) { - Ok(val) => Value::Int { val, span }, - Err(error) => Value::Error { - error: Box::new(error), - span, - }, + Ok(val) => Value::int(val, span), + Err(error) => Value::error(error, span), } } else { convert_int(input, span, radix) @@ -273,15 +273,12 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { } Value::Bool { val, .. } => { if *val { - Value::Int { val: 1, span } + Value::int(1, span) } else { - Value::Int { val: 0, span } + Value::int(0, span) } } - Value::Date { - val, - span: val_span, - } => { + Value::Date { val, .. } => { if val < &FixedOffset::east_opt(0) .expect("constant") @@ -293,23 +290,20 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { .with_ymd_and_hms(2262, 4, 11, 23, 47, 16) .unwrap() { - Value::Error { - error: Box::new(ShellError::IncorrectValue { + Value::error ( + ShellError::IncorrectValue { msg: "DateTime out of range for timestamp: 1677-09-21T00:12:43Z to 2262-04-11T23:47:16".to_string(), - val_span: *val_span, + val_span, call_span: span, - }), + }, span, - } + ) } else { - Value::Int { - val: val.timestamp_nanos(), - span, - } + Value::int(val.timestamp_nanos(), span) } } - Value::Duration { val, .. } => Value::Int { val: *val, span }, - Value::Binary { val, span } => { + Value::Duration { val, .. } => Value::int(*val, span), + Value::Binary { val, .. } => { use byteorder::{BigEndian, ByteOrder, LittleEndian}; let mut val = val.to_vec(); @@ -320,28 +314,28 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { } val.resize(8, 0); - Value::int(LittleEndian::read_i64(&val), *span) + Value::int(LittleEndian::read_i64(&val), val_span) } else { while val.len() < 8 { val.insert(0, 0); } val.resize(8, 0); - Value::int(BigEndian::read_i64(&val), *span) + Value::int(BigEndian::read_i64(&val), val_span) } } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "integer, float, filesize, date, string, binary, duration or bool" .into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }, + ), } } @@ -357,27 +351,22 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value { { match int_from_string(val, head) { Ok(x) => return Value::int(x, head), - Err(e) => { - return Value::Error { - error: Box::new(e), - span: head, - } - } + Err(e) => return Value::error(e, head), } } else if val.starts_with("00") { // It's a padded string match i64::from_str_radix(val, radix) { Ok(n) => return Value::int(n, head), Err(e) => { - return Value::Error { - error: Box::new(ShellError::CantConvert { + return Value::error( + ShellError::CantConvert { to_type: "string".to_string(), from_type: "int".to_string(), span: head, help: Some(e.to_string()), - }), - span: head, - } + }, + head, + ) } } } @@ -386,28 +375,28 @@ fn convert_int(input: &Value, head: Span, radix: u32) -> Value { // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => return input.clone(), other => { - return Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + return Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string and integer".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }; + }, + head, + ); } }; match i64::from_str_radix(i.trim(), radix) { Ok(n) => Value::int(n, head), - Err(_reason) => Value::Error { - error: Box::new(ShellError::CantConvert { + Err(_reason) => Value::error( + ShellError::CantConvert { to_type: "string".to_string(), from_type: "int".to_string(), span: head, help: None, - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/conversions/into/record.rs b/crates/nu-command/src/conversions/into/record.rs index 45ded57d9..35d48d558 100644 --- a/crates/nu-command/src/conversions/into/record.rs +++ b/crates/nu-command/src/conversions/into/record.rs @@ -62,9 +62,9 @@ impl Command for SubCommand { result: Some(Value::test_record(Record { cols: vec!["0".to_string(), "1".to_string(), "2".to_string()], vals: vec![ - Value::Int { val: 1, span }, - Value::Int { val: 2, span }, - Value::Int { val: 3, span }, + Value::int(1, span), + Value::int(2, span), + Value::int(3, span), ], })), }, @@ -74,9 +74,9 @@ impl Command for SubCommand { result: Some(Value::test_record(Record { cols: vec!["0".to_string(), "1".to_string(), "2".to_string()], vals: vec![ - Value::Int { val: 0, span }, - Value::Int { val: 1, span }, - Value::Int { val: 2, span }, + Value::int(0, span), + Value::int(1, span), + Value::int(2, span), ], })), }, @@ -92,14 +92,11 @@ impl Command for SubCommand { "sign".into(), ], vals: vec![ - Value::Int { val: 71, span }, - Value::Int { val: 3, span }, - Value::Int { val: 4, span }, - Value::Int { val: 5, span }, - Value::String { - val: "-".into(), - span, - }, + Value::int(71, span), + Value::int(3, span), + Value::int(4, span), + Value::int(5, span), + Value::string("-", span), ], })), }, @@ -108,7 +105,7 @@ impl Command for SubCommand { example: "{a: 1, b: 2} | into record", result: Some(Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], - vals: vec![Value::Int { val: 1, span }, Value::Int { val: 2, span }], + vals: vec![Value::int(1, span), Value::int(2, span)], })), }, Example { @@ -125,16 +122,13 @@ impl Command for SubCommand { "timezone".into(), ], vals: vec![ - Value::Int { val: 2020, span }, - Value::Int { val: 4, span }, - Value::Int { val: 12, span }, - Value::Int { val: 22, span }, - Value::Int { val: 10, span }, - Value::Int { val: 57, span }, - Value::String { - val: "+02:00".to_string(), - span, - }, + Value::int(2020, span), + Value::int(4, span), + Value::int(12, span), + Value::int(22, span), + Value::int(10, span), + Value::int(57, span), + Value::string("+02:00".to_string(), span), ], })), }, @@ -149,10 +143,11 @@ fn into_record( ) -> Result { let input = input.into_value(call.head); let input_type = input.get_type(); + let span = input.span(); let res = match input { - Value::Date { val, span } => parse_date_into_record(val, span), - Value::Duration { val, span } => parse_duration_into_record(val, span), - Value::List { mut vals, span } => match input_type { + Value::Date { val, .. } => parse_date_into_record(val, span), + Value::Duration { val, .. } => parse_duration_into_record(val, span), + Value::List { mut vals, .. } => match input_type { Type::Table(..) if vals.len() == 1 => vals.pop().expect("already checked 1 item"), _ => Value::record( vals.into_iter() @@ -162,24 +157,24 @@ fn into_record( span, ), }, - Value::Range { val, span } => Value::record( + Value::Range { val, .. } => Value::record( val.into_range_iter(engine_state.ctrlc.clone())? .enumerate() .map(|(idx, val)| (format!("{idx}"), val)) .collect(), span, ), - Value::Record { val, span } => Value::Record { val, span }, + Value::Record { val, .. } => Value::record(val, span), Value::Error { .. } => input, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: other.get_type().to_string(), dst_span: call.head, src_span: other.span(), - }), - span: call.head, - }, + }, + call.head, + ), }; Ok(res.into_pipeline_data()) } diff --git a/crates/nu-command/src/conversions/into/string.rs b/crates/nu-command/src/conversions/into/string.rs index f5d1a8801..780a0cf26 100644 --- a/crates/nu-command/src/conversions/into/string.rs +++ b/crates/nu-command/src/conversions/into/string.rs @@ -182,22 +182,16 @@ fn string_helper( }; match input { - PipelineData::ExternalStream { stdout: None, .. } => Ok(Value::String { - val: String::new(), - span: head, + PipelineData::ExternalStream { stdout: None, .. } => { + Ok(Value::string(String::new(), head).into_pipeline_data()) } - .into_pipeline_data()), PipelineData::ExternalStream { stdout: Some(stream), .. } => { // TODO: in the future, we may want this to stream out, converting each to bytes let output = stream.into_string()?; - Ok(Value::String { - val: output.item, - span: head, - } - .into_pipeline_data()) + Ok(Value::string(output.item, head).into_pipeline_data()) } _ => operate(action, args, input, head, engine_state.ctrlc.clone()), } @@ -211,80 +205,53 @@ fn action(input: &Value, args: &Arguments, span: Span) -> Value { Value::Int { val, .. } => { let decimal_value = digits.unwrap_or(0) as usize; let res = format_int(*val, false, decimal_value); - Value::String { val: res, span } + Value::string(res, span) } Value::Float { val, .. } => { if decimals { let decimal_value = digits.unwrap_or(2) as usize; - Value::String { - val: format!("{val:.decimal_value$}"), - span, - } + Value::string(format!("{val:.decimal_value$}"), span) } else { - Value::String { - val: val.to_string(), - span, - } + Value::string(val.to_string(), span) } } - Value::Bool { val, .. } => Value::String { - val: val.to_string(), - span, - }, - Value::Date { val, .. } => Value::String { - val: val.format("%c").to_string(), - span, - }, - Value::String { val, .. } => Value::String { - val: val.to_string(), - span, - }, + Value::Bool { val, .. } => Value::string(val.to_string(), span), + Value::Date { val, .. } => Value::string(val.format("%c").to_string(), span), + Value::String { val, .. } => Value::string(val.to_string(), span), - Value::Filesize { val: _, .. } => Value::String { - val: input.into_string(", ", config), - span, - }, - Value::Duration { val: _, .. } => Value::String { - val: input.into_string("", config), - span, - }, + Value::Filesize { val: _, .. } => Value::string(input.into_string(", ", config), span), + Value::Duration { val: _, .. } => Value::string(input.into_string("", config), span), - Value::Error { error, .. } => Value::String { - val: into_code(error).unwrap_or_default(), - span, - }, - Value::Nothing { .. } => Value::String { - val: "".to_string(), - span, - }, - Value::Record { .. } => Value::Error { + Value::Error { error, .. } => Value::string(into_code(error).unwrap_or_default(), span), + Value::Nothing { .. } => Value::string("".to_string(), span), + Value::Record { .. } => Value::error( // Watch out for CantConvert's argument order - error: Box::new(ShellError::CantConvert { + ShellError::CantConvert { to_type: "string".into(), from_type: "record".into(), span, help: Some("try using the `to nuon` command".into()), - }), + }, span, - }, - Value::Binary { .. } => Value::Error { - error: Box::new(ShellError::CantConvert { + ), + Value::Binary { .. } => Value::error( + ShellError::CantConvert { to_type: "string".into(), from_type: "binary".into(), span, help: Some("try using the `decode` command".into()), - }), + }, span, - }, - x => Value::Error { - error: Box::new(ShellError::CantConvert { + ), + x => Value::error( + ShellError::CantConvert { to_type: String::from("string"), from_type: x.get_type().to_string(), span, help: None, - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/database/commands/into_sqlite.rs b/crates/nu-command/src/database/commands/into_sqlite.rs index bffad8ed7..bdaa135a3 100644 --- a/crates/nu-command/src/database/commands/into_sqlite.rs +++ b/crates/nu-command/src/database/commands/into_sqlite.rs @@ -109,8 +109,9 @@ fn action( "main".to_string() }; + let val_span = input.span(); match input { - Value::List { vals, span } => { + Value::List { vals, .. } => { // find the column names, and sqlite data types let columns = get_columns_with_sqlite_types(vals); @@ -135,11 +136,10 @@ fn action( .join(",") } // Number formats so keep them without quotes - Value::Int { val: _, span: _ } - | Value::Float { val: _, span: _ } - | Value::Filesize { val: _, span: _ } - | Value::Duration { val: _, span: _ } => - nu_value_to_string(list_value.clone(), ""), + Value::Int { .. } + | Value::Float { .. } + | Value::Filesize { .. } + | Value::Duration { .. } => nu_value_to_string(list_value.clone(), ""), _ => // String formats so add quotes around them format!("'{}'", nu_value_to_string(list_value.clone(), "")), @@ -210,7 +210,7 @@ fn action( })?; // and we're done - Ok(Value::Nothing { span: *span }) + Ok(Value::nothing(val_span)) } // Propagate errors by explicitly matching them before the final case. Value::Error { error, .. } => Err(*error.clone()), diff --git a/crates/nu-command/src/database/values/sqlite.rs b/crates/nu-command/src/database/values/sqlite.rs index 18e5be698..386ac2e3a 100644 --- a/crates/nu-command/src/database/values/sqlite.rs +++ b/crates/nu-command/src/database/values/sqlite.rs @@ -56,8 +56,9 @@ impl SQLiteDatabase { } pub fn try_from_value(value: Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { Some(db) => Ok(Self { path: db.path.clone(), ctrlc: db.ctrlc.clone(), @@ -84,10 +85,7 @@ impl SQLiteDatabase { } pub fn into_value(self, span: Span) -> Value { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } pub fn query(&self, sql: &Spanned, call_span: Span) -> Result { @@ -280,10 +278,7 @@ impl CustomValue for SQLiteDatabase { ctrlc: self.ctrlc.clone(), }; - Value::CustomValue { - val: Box::new(cloned), - span, - } + Value::custom_value(Box::new(cloned), span) } fn value_string(&self) -> String { @@ -393,10 +388,7 @@ fn prepared_statement_to_nu_list( for row_result in row_results { if nu_utils::ctrl_c::was_pressed(&ctrlc) { // return whatever we have so far, let the caller decide whether to use it - return Ok(Value::List { - vals: row_values, - span: call_span, - }); + return Ok(Value::list(row_values, call_span)); } if let Ok(row_value) = row_result { @@ -404,10 +396,7 @@ fn prepared_statement_to_nu_list( } } - Ok(Value::List { - vals: row_values, - span: call_span, - }) + Ok(Value::list(row_values, call_span)) } fn read_entire_sqlite_db( @@ -450,28 +439,17 @@ pub fn convert_sqlite_row_to_nu_value(row: &Row, span: Span, column_names: Vec Value { match value { - ValueRef::Null => Value::Nothing { span }, - ValueRef::Integer(i) => Value::Int { val: i, span }, - ValueRef::Real(f) => Value::Float { val: f, span }, + ValueRef::Null => Value::nothing(span), + ValueRef::Integer(i) => Value::int(i, span), + ValueRef::Real(f) => Value::float(f, span), ValueRef::Text(buf) => { let s = match std::str::from_utf8(buf) { Ok(v) => v, - Err(_) => { - return Value::Error { - error: Box::new(ShellError::NonUtf8(span)), - span, - } - } + Err(_) => return Value::error(ShellError::NonUtf8(span), span), }; - Value::String { - val: s.to_string(), - span, - } + Value::string(s.to_string(), span) } - ValueRef::Blob(u) => Value::Binary { - val: u.to_vec(), - span, - }, + ValueRef::Blob(u) => Value::binary(u.to_vec(), span), } } @@ -506,10 +484,7 @@ mod test { let expected = Value::test_record(Record { cols: vec!["person".to_string()], - vals: vec![Value::List { - vals: vec![], - span: Span::test_data(), - }], + vals: vec![Value::list(vec![], Span::test_data())], }); assert_eq!(converted_db, expected); @@ -539,25 +514,22 @@ mod test { let expected = Value::test_record(Record { cols: vec!["item".to_string()], - vals: vec![Value::List { - vals: vec![ + vals: vec![Value::list( + vec![ Value::test_record(Record { cols: vec!["id".to_string(), "name".to_string()], - vals: vec![Value::Int { val: 123, span }, Value::Nothing { span }], + vals: vec![Value::int(123, span), Value::nothing(span)], }), Value::test_record(Record { cols: vec!["id".to_string(), "name".to_string()], vals: vec![ - Value::Int { val: 456, span }, - Value::String { - val: "foo bar".to_string(), - span, - }, + Value::int(456, span), + Value::string("foo bar".to_string(), span), ], }), ], span, - }], + )], }); assert_eq!(converted_db, expected); diff --git a/crates/nu-command/src/date/date_.rs b/crates/nu-command/src/date/date_.rs index b875ac24e..81ab887d9 100644 --- a/crates/nu-command/src/date/date_.rs +++ b/crates/nu-command/src/date/date_.rs @@ -58,15 +58,15 @@ fn date( ) -> Result { let head = call.head; - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Date.signature(), &Date.examples(), engine_state, stack, false, ), - span: head, - } + head, + ) .into_pipeline_data()) } diff --git a/crates/nu-command/src/date/humanize.rs b/crates/nu-command/src/date/humanize.rs index 33ce986a0..1d8c41612 100644 --- a/crates/nu-command/src/date/humanize.rs +++ b/crates/nu-command/src/date/humanize.rs @@ -64,35 +64,24 @@ impl Command for SubCommand { } fn helper(value: Value, head: Span) -> Value { + let span = value.span(); match value { - Value::Nothing { span: _ } => { + Value::Nothing { .. } => { let dt = Local::now(); - Value::String { - val: humanize_date(dt.with_timezone(dt.offset())), - span: head, - } + Value::string(humanize_date(dt.with_timezone(dt.offset())), head) } - Value::String { - val, - span: val_span, - } => { - let dt = parse_date_from_string(&val, val_span); + Value::String { val, .. } => { + let dt = parse_date_from_string(&val, span); match dt { - Ok(x) => Value::String { - val: humanize_date(x), - span: head, - }, + Ok(x) => Value::string(humanize_date(x), head), Err(e) => e, } } - Value::Date { val, span: _ } => Value::String { - val: humanize_date(val), - span: head, - }, - _ => Value::Error { - error: Box::new(ShellError::DatetimeParseError(value.debug_value(), head)), - span: head, - }, + Value::Date { val, .. } => Value::string(humanize_date(val), head), + _ => Value::error( + ShellError::DatetimeParseError(value.debug_value(), head), + head, + ), } } diff --git a/crates/nu-command/src/date/list_timezone.rs b/crates/nu-command/src/date/list_timezone.rs index a08453a0b..3867884a9 100644 --- a/crates/nu-command/src/date/list_timezone.rs +++ b/crates/nu-command/src/date/list_timezone.rs @@ -52,13 +52,13 @@ impl Command for SubCommand { vec![Example { example: "date list-timezone | where timezone =~ Shanghai", description: "Show timezone(s) that contains 'Shanghai'", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["timezone".into()], vals: vec![Value::test_string("Asia/Shanghai")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } diff --git a/crates/nu-command/src/date/now.rs b/crates/nu-command/src/date/now.rs index 275bbeb02..4a655a846 100644 --- a/crates/nu-command/src/date/now.rs +++ b/crates/nu-command/src/date/now.rs @@ -35,11 +35,7 @@ impl Command for SubCommand { ) -> Result { let head = call.head; let dt = Local::now(); - Ok(Value::Date { - val: dt.with_timezone(dt.offset()), - span: head, - } - .into_pipeline_data()) + Ok(Value::date(dt.with_timezone(dt.offset()), head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/date/to_record.rs b/crates/nu-command/src/date/to_record.rs index 55d2c958b..f5b4a7c04 100644 --- a/crates/nu-command/src/date/to_record.rs +++ b/crates/nu-command/src/date/to_record.rs @@ -62,20 +62,14 @@ impl Command for SubCommand { "timezone".into(), ]; let vals = vec![ - Value::Int { val: 2020, span }, - Value::Int { val: 4, span }, - Value::Int { val: 12, span }, - Value::Int { val: 22, span }, - Value::Int { val: 10, span }, - Value::Int { val: 57, span }, - Value::Int { - val: 123_000_000, - span, - }, - Value::String { - val: "+02:00".to_string(), - span, - }, + Value::int(2020, span), + Value::int(4, span), + Value::int(12, span), + Value::int(22, span), + Value::int(10, span), + Value::int(57, span), + Value::int(123_000_000, span), + Value::string("+02:00", span), ]; Some(Value::test_record(Record { cols, vals })) }; @@ -93,17 +87,14 @@ impl Command for SubCommand { "timezone".into(), ]; let vals = vec![ - Value::Int { val: 2020, span }, - Value::Int { val: 4, span }, - Value::Int { val: 12, span }, - Value::Int { val: 22, span }, - Value::Int { val: 10, span }, - Value::Int { val: 57, span }, - Value::Int { val: 0, span }, - Value::String { - val: "+02:00".to_string(), - span, - }, + Value::int(2020, span), + Value::int(4, span), + Value::int(12, span), + Value::int(22, span), + Value::int(10, span), + Value::int(57, span), + Value::int(0, span), + Value::string("+02:00", span), ]; Some(Value::test_record(Record { cols, vals })) }; @@ -150,24 +141,19 @@ fn parse_date_into_table(date: DateTime, head: Span) -> Value { } fn helper(val: Value, head: Span) -> Value { + let span = val.span(); match val { - Value::String { - val, - span: val_span, - } => match parse_date_from_string(&val, val_span) { + Value::String { val, .. } => match parse_date_from_string(&val, span) { Ok(date) => parse_date_into_table(date, head), Err(e) => e, }, - Value::Nothing { span: _ } => { + Value::Nothing { .. } => { let now = Local::now(); let n = now.with_timezone(now.offset()); parse_date_into_table(n, head) } - Value::Date { val, span: _ } => parse_date_into_table(val, head), - _ => Value::Error { - error: Box::new(DatetimeParseError(val.debug_value(), head)), - span: head, - }, + Value::Date { val, .. } => parse_date_into_table(val, head), + _ => Value::error(DatetimeParseError(val.debug_value(), head), head), } } diff --git a/crates/nu-command/src/date/to_table.rs b/crates/nu-command/src/date/to_table.rs index aaf33f3fb..1786d8103 100644 --- a/crates/nu-command/src/date/to_table.rs +++ b/crates/nu-command/src/date/to_table.rs @@ -62,22 +62,19 @@ impl Command for SubCommand { "timezone".into(), ]; let vals = vec![ - Value::Int { val: 2020, span }, - Value::Int { val: 4, span }, - Value::Int { val: 12, span }, - Value::Int { val: 22, span }, - Value::Int { val: 10, span }, - Value::Int { val: 57, span }, - Value::Int { val: 789, span }, - Value::String { - val: "+02:00".to_string(), - span, - }, + Value::int(2020, span), + Value::int(4, span), + Value::int(12, span), + Value::int(22, span), + Value::int(10, span), + Value::int(57, span), + Value::int(789, span), + Value::string("+02:00".to_string(), span), ]; - Some(Value::List { - vals: vec![Value::test_record(Record { cols, vals })], + Some(Value::list( + vec![Value::test_record(Record { cols, vals })], span, - }) + )) }; let example_result_2 = || { @@ -93,22 +90,19 @@ impl Command for SubCommand { "timezone".into(), ]; let vals = vec![ - Value::Int { val: 2020, span }, - Value::Int { val: 4, span }, - Value::Int { val: 12, span }, - Value::Int { val: 22, span }, - Value::Int { val: 10, span }, - Value::Int { val: 57, span }, - Value::Int { val: 0, span }, - Value::String { - val: "+02:00".to_string(), - span, - }, + Value::int(2020, span), + Value::int(4, span), + Value::int(12, span), + Value::int(22, span), + Value::int(10, span), + Value::int(57, span), + Value::int(0, span), + Value::string("+02:00".to_string(), span), ]; - Some(Value::List { - vals: vec![Value::test_record(Record { cols, vals })], + Some(Value::list( + vec![Value::test_record(Record { cols, vals })], span, - }) + )) }; vec![ @@ -152,24 +146,19 @@ fn parse_date_into_table(date: DateTime, head: Span) -> Value { } fn helper(val: Value, head: Span) -> Value { + let val_span = val.span(); match val { - Value::String { - val, - span: val_span, - } => match parse_date_from_string(&val, val_span) { + Value::String { val, .. } => match parse_date_from_string(&val, val_span) { Ok(date) => parse_date_into_table(date, head), Err(e) => e, }, - Value::Nothing { span: _ } => { + Value::Nothing { .. } => { let now = Local::now(); let n = now.with_timezone(now.offset()); parse_date_into_table(n, head) } - Value::Date { val, span: _ } => parse_date_into_table(val, head), - _ => Value::Error { - error: Box::new(DatetimeParseError(val.debug_value(), head)), - span: head, - }, + Value::Date { val, .. } => parse_date_into_table(val, head), + _ => Value::error(DatetimeParseError(val.debug_value(), head), head), } } diff --git a/crates/nu-command/src/date/to_timezone.rs b/crates/nu-command/src/date/to_timezone.rs index 9afcbad5a..a3e778160 100644 --- a/crates/nu-command/src/date/to_timezone.rs +++ b/crates/nu-command/src/date/to_timezone.rs @@ -71,10 +71,7 @@ impl Command for SubCommand { .expect("to timezone: help example is invalid") .with_ymd_and_hms(2020, 10, 10, 13, 00, 00) { - LocalResult::Single(dt) => Some(Value::Date { - val: dt, - span: Span::test_data(), - }), + LocalResult::Single(dt) => Some(Value::date(dt, Span::test_data())), _ => panic!("to timezone: help example is invalid"), }; @@ -109,12 +106,10 @@ impl Command for SubCommand { } fn helper(value: Value, head: Span, timezone: &Spanned) -> Value { + let val_span = value.span(); match value { - Value::Date { val, span: _ } => _to_timezone(val, timezone, head), - Value::String { - val, - span: val_span, - } => { + Value::Date { val, .. } => _to_timezone(val, timezone, head), + Value::String { val, .. } => { let time = parse_date_from_string(&val, val_span); match time { Ok(dt) => _to_timezone(dt, timezone, head), @@ -122,27 +117,27 @@ fn helper(value: Value, head: Span, timezone: &Spanned) -> Value { } } - Value::Nothing { span: _ } => { + Value::Nothing { .. } => { let dt = Local::now(); _to_timezone(dt.with_timezone(dt.offset()), timezone, head) } - _ => Value::Error { - error: Box::new(ShellError::DatetimeParseError(value.debug_value(), head)), - span: head, - }, + _ => Value::error( + ShellError::DatetimeParseError(value.debug_value(), head), + head, + ), } } fn _to_timezone(dt: DateTime, timezone: &Spanned, span: Span) -> Value { match datetime_in_timezone(&dt, timezone.item.as_str()) { - Ok(dt) => Value::Date { val: dt, span }, - Err(_) => Value::Error { - error: Box::new(ShellError::TypeMismatch { + Ok(dt) => Value::date(dt, span), + Err(_) => Value::error( + ShellError::TypeMismatch { err_message: String::from("invalid time zone"), span: timezone.span, - }), - span: timezone.span, - }, + }, + timezone.span, + ), } } diff --git a/crates/nu-command/src/date/utils.rs b/crates/nu-command/src/date/utils.rs index 3df3fcc59..d70437cbb 100644 --- a/crates/nu-command/src/date/utils.rs +++ b/crates/nu-command/src/date/utils.rs @@ -14,16 +14,16 @@ pub(crate) fn parse_date_from_string( match offset.from_local_datetime(&native_dt) { LocalResult::Single(d) => Ok(d), LocalResult::Ambiguous(d, _) => Ok(d), - LocalResult::None => Err(Value::Error { - error: Box::new(ShellError::DatetimeParseError(input.to_string(), span)), + LocalResult::None => Err(Value::error( + ShellError::DatetimeParseError(input.to_string(), span), span, - }), + )), } } - Err(_) => Err(Value::Error { - error: Box::new(ShellError::DatetimeParseError(input.to_string(), span)), + Err(_) => Err(Value::error( + ShellError::DatetimeParseError(input.to_string(), span), span, - }), + )), } } @@ -289,8 +289,5 @@ pub(crate) fn generate_strftime_list(head: Span, show_parse_only_formats: bool) )); } - Value::List { - vals: records, - span: head, - } + Value::list(records, head) } diff --git a/crates/nu-command/src/debug/ast.rs b/crates/nu-command/src/debug/ast.rs index ea3c6800b..1ccabdc71 100644 --- a/crates/nu-command/src/debug/ast.rs +++ b/crates/nu-command/src/debug/ast.rs @@ -97,22 +97,22 @@ impl Command for Ast { ); Ok(output_record.into_pipeline_data()) } else { - let block_value = Value::String { - val: if minify { + let block_value = Value::string( + if minify { format!("{block_output:?}") } else { format!("{block_output:#?}") }, - span: pipeline.span, - }; - let error_value = Value::String { - val: if minify { + pipeline.span, + ); + let error_value = Value::string( + if minify { format!("{error_output:?}") } else { format!("{error_output:#?}") }, - span: pipeline.span, - }; + pipeline.span, + ); let output_record = Value::record( record! { "block" => block_value, diff --git a/crates/nu-command/src/debug/debug_.rs b/crates/nu-command/src/debug/debug_.rs index 34be1be10..10c5dccba 100644 --- a/crates/nu-command/src/debug/debug_.rs +++ b/crates/nu-command/src/debug/debug_.rs @@ -44,15 +44,9 @@ impl Command for Debug { input.map( move |x| { if raw { - Value::String { - val: x.debug_value(), - span: head, - } + Value::string(x.debug_value(), head) } else { - Value::String { - val: x.debug_string(", ", &config), - span: head, - } + Value::string(x.debug_string(", ", &config), head) } }, engine_state.ctrlc.clone(), @@ -69,23 +63,23 @@ impl Command for Debug { Example { description: "Debug print a list", example: "['hello'] | debug", - result: Some(Value::List { - vals: vec![Value::test_string("hello")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("hello")], + Span::test_data(), + )), }, Example { description: "Debug print a table", example: "[[version patch]; ['0.1.0' false] ['0.1.1' true] ['0.2.0' false]] | debug", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("{version: 0.1.0, patch: false}"), Value::test_string("{version: 0.1.1, patch: true}"), Value::test_string("{version: 0.2.0, patch: false}"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/debug/explain.rs b/crates/nu-command/src/debug/explain.rs index 615c20f1a..39acd835d 100644 --- a/crates/nu-command/src/debug/explain.rs +++ b/crates/nu-command/src/debug/explain.rs @@ -213,10 +213,7 @@ fn get_expression_as_value( ) -> Value { match eval_expression(engine_state, stack, inner_expr) { Ok(v) => v, - Err(error) => Value::Error { - error: Box::new(error), - span: inner_expr.span, - }, + Err(error) => Value::error(error, inner_expr.span), } } diff --git a/crates/nu-command/src/debug/inspect_table.rs b/crates/nu-command/src/debug/inspect_table.rs index 2ffe0ec7d..58fdad90b 100644 --- a/crates/nu-command/src/debug/inspect_table.rs +++ b/crates/nu-command/src/debug/inspect_table.rs @@ -198,6 +198,7 @@ mod util { /// Try to build column names and a table grid. pub fn collect_input(value: Value) -> (Vec, Vec>) { + let span = value.span(); match value { Value::Record { val: record, .. } => ( record.cols, @@ -217,13 +218,10 @@ mod util { (columns, data) } - Value::String { val, span } => { + Value::String { val, .. } => { let lines = val .lines() - .map(|line| Value::String { - val: line.to_string(), - span, - }) + .map(|line| Value::string(line.to_string(), span)) .map(|val| vec![debug_string_without_formatting(&val)]) .collect(); diff --git a/crates/nu-command/src/debug/timeit.rs b/crates/nu-command/src/debug/timeit.rs index 8b7fc2c6d..8188b0f3f 100644 --- a/crates/nu-command/src/debug/timeit.rs +++ b/crates/nu-command/src/debug/timeit.rs @@ -79,10 +79,7 @@ impl Command for TimeIt { let end_time = Instant::now(); - let output = Value::Duration { - val: (end_time - start_time).as_nanos() as i64, - span: call.head, - }; + let output = Value::duration((end_time - start_time).as_nanos() as i64, call.head); Ok(output.into_pipeline_data()) } diff --git a/crates/nu-command/src/debug/view.rs b/crates/nu-command/src/debug/view.rs index b92ec5d6d..9d644ff7e 100644 --- a/crates/nu-command/src/debug/view.rs +++ b/crates/nu-command/src/debug/view.rs @@ -34,16 +34,16 @@ impl Command for View { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &View.signature(), &View.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/debug/view_files.rs b/crates/nu-command/src/debug/view_files.rs index 54581dfb3..ff38103ad 100644 --- a/crates/nu-command/src/debug/view_files.rs +++ b/crates/nu-command/src/debug/view_files.rs @@ -47,11 +47,7 @@ impl Command for ViewFiles { )); } - Ok(Value::List { - vals: records, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::list(records, call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/env/config/config_.rs b/crates/nu-command/src/env/config/config_.rs index 18ae5c6c2..6a2a483ca 100644 --- a/crates/nu-command/src/env/config/config_.rs +++ b/crates/nu-command/src/env/config/config_.rs @@ -34,16 +34,16 @@ impl Command for ConfigMeta { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &ConfigMeta.signature(), &ConfigMeta.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } diff --git a/crates/nu-command/src/env/export_env.rs b/crates/nu-command/src/env/export_env.rs index 53c90f92e..487205081 100644 --- a/crates/nu-command/src/env/export_env.rs +++ b/crates/nu-command/src/env/export_env.rs @@ -58,9 +58,7 @@ impl Command for ExportEnv { Example { description: "Set an environment variable", example: r#"export-env { $env.SPAM = 'eggs' }"#, - result: Some(Value::Nothing { - span: Span::test_data(), - }), + result: Some(Value::nothing(Span::test_data())), }, Example { description: "Set an environment variable and examine its value", diff --git a/crates/nu-command/src/filesystem/cd.rs b/crates/nu-command/src/filesystem/cd.rs index 8f597e461..18ce5a5df 100644 --- a/crates/nu-command/src/filesystem/cd.rs +++ b/crates/nu-command/src/filesystem/cd.rs @@ -159,10 +159,7 @@ impl Command for Cd { } }; - let path_value = Value::String { - val: path.clone(), - span, - }; + let path_value = Value::string(path.clone(), span); if let Some(oldpwd) = stack.get_env_var(engine_state, "PWD") { stack.add_env_var("OLDPWD".into(), oldpwd) diff --git a/crates/nu-command/src/filesystem/cp.rs b/crates/nu-command/src/filesystem/cp.rs index 3fc52a95e..cb18ec9f3 100644 --- a/crates/nu-command/src/filesystem/cp.rs +++ b/crates/nu-command/src/filesystem/cp.rs @@ -394,19 +394,13 @@ fn interactive_copy( format!("cp: overwrite '{}'? ", dst.to_string_lossy()), ); if let Err(e) = interaction { - Value::Error { - error: Box::new(ShellError::GenericError( - e.to_string(), - e.to_string(), - Some(span), - None, - Vec::new(), - )), + Value::error( + ShellError::GenericError(e.to_string(), e.to_string(), Some(span), None, Vec::new()), span, - } + ) } else if !confirmed { let msg = format!("{:} not copied to {:}", src.display(), dst.display()); - Value::String { val: msg, span } + Value::string(msg, span) } else { copy_impl(src, dst, span, &None) } @@ -425,7 +419,7 @@ fn copy_file( match std::fs::copy(&src, &dst) { Ok(_) => { let msg = format!("copied {:} to {:}", src.display(), dst.display()); - Value::String { val: msg, span } + Value::string(msg, span) } Err(e) => convert_io_error(e, src, dst, span), } @@ -521,7 +515,7 @@ fn copy_file_with_progressbar( let msg = format!("copied {:} to {:}", src.display(), dst.display()); bar.finished_msg(format!(" {} copied!", &file_name)); - Value::String { val: msg, span } + Value::string(msg, span) } fn copy_symlink( @@ -534,16 +528,16 @@ fn copy_symlink( let target_path = match target_path { Ok(p) => p, Err(err) => { - return Value::Error { - error: Box::new(ShellError::GenericError( + return Value::error( + ShellError::GenericError( err.to_string(), err.to_string(), Some(span), None, vec![], - )), + ), span, - } + ) } }; @@ -566,18 +560,12 @@ fn copy_symlink( match create_symlink(target_path.as_path(), dst.as_path()) { Ok(_) => { let msg = format!("copied {:} to {:}", src.display(), dst.display()); - Value::String { val: msg, span } + Value::string(msg, span) } - Err(e) => Value::Error { - error: Box::new(ShellError::GenericError( - e.to_string(), - e.to_string(), - Some(span), - None, - vec![], - )), + Err(e) => Value::error( + ShellError::GenericError(e.to_string(), e.to_string(), Some(span), None, vec![]), span, - }, + ), } } @@ -618,8 +606,5 @@ fn convert_io_error(error: std::io::Error, src: PathBuf, dst: PathBuf, span: Spa _ => ShellError::IOErrorSpanned(message_src, span), }; - Value::Error { - error: Box::new(shell_error), - span, - } + Value::error(shell_error, span) } diff --git a/crates/nu-command/src/filesystem/glob.rs b/crates/nu-command/src/filesystem/glob.rs index b0360b767..408df8067 100644 --- a/crates/nu-command/src/filesystem/glob.rs +++ b/crates/nu-command/src/filesystem/glob.rs @@ -142,16 +142,19 @@ impl Command for Glob { let no_files = call.has_flag("no-file"); let no_symlinks = call.has_flag("no-symlink"); - let (not_patterns, not_pattern_span): (Vec, Span) = if let Some(Value::List { - vals: pats, - span: pat_span, - }) = - call.get_flag(engine_state, stack, "not")? - { - let p = convert_patterns(pats.as_slice())?; - (p, pat_span) - } else { - (vec![], span) + let not_flag: Option = call.get_flag(engine_state, stack, "not")?; + let (not_patterns, not_pattern_span): (Vec, Span) = match not_flag { + None => (vec![], span), + Some(f) => { + let pat_span = f.span(); + match f { + Value::List { vals: pats, .. } => { + let p = convert_patterns(pats.as_slice())?; + (p, pat_span) + } + _ => (vec![], span), + } + } }; if glob_pattern.item.is_empty() { @@ -261,10 +264,10 @@ fn glob_to_value<'a>( || no_files && file_type.is_file() || no_symlinks && file_type.is_symlink()) { - result.push(Value::String { - val: entry.into_path().to_string_lossy().to_string(), + result.push(Value::string( + entry.into_path().to_string_lossy().to_string(), span, - }); + )); } } diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index 2b47e6031..8964f61f6 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -255,19 +255,13 @@ impl Command for Ls { ); match entry { Ok(value) => Some(value), - Err(err) => Some(Value::Error { - error: Box::new(err), - span: call_span, - }), + Err(err) => Some(Value::error(err, call_span)), } } - Err(err) => Some(Value::Error { - error: Box::new(err), - span: call_span, - }), + Err(err) => Some(Value::error(err, call_span)), } } - _ => Some(Value::Nothing { span: call_span }), + _ => Some(Value::nothing(call_span)), }) .into_pipeline_data_with_metadata( Box::new(PipelineMetadata { diff --git a/crates/nu-command/src/filesystem/mkdir.rs b/crates/nu-command/src/filesystem/mkdir.rs index 851ab748d..703ac4898 100644 --- a/crates/nu-command/src/filesystem/mkdir.rs +++ b/crates/nu-command/src/filesystem/mkdir.rs @@ -79,7 +79,7 @@ impl Command for Mkdir { if is_verbose { let val = format!("{:}", dir.to_string_lossy()); - stream.push_back(Value::String { val, span }); + stream.push_back(Value::string(val, span)); } } diff --git a/crates/nu-command/src/filesystem/mv.rs b/crates/nu-command/src/filesystem/mv.rs index 6e7e88232..43e3b5719 100644 --- a/crates/nu-command/src/filesystem/mv.rs +++ b/crates/nu-command/src/filesystem/mv.rs @@ -200,10 +200,7 @@ impl Command for Mv { update_mode, ); if let Err(error) = result { - Some(Value::Error { - error: Box::new(error), - span: spanned_source.span, - }) + Some(Value::error(error, spanned_source.span)) } else if verbose { let val = match result { Ok(true) => format!( @@ -217,7 +214,7 @@ impl Command for Mv { destination.to_string_lossy() ), }; - Some(Value::String { val, span }) + Some(Value::string(val, span)) } else { None } diff --git a/crates/nu-command/src/filesystem/rm.rs b/crates/nu-command/src/filesystem/rm.rs index cd97d40d9..5c9e95201 100644 --- a/crates/nu-command/src/filesystem/rm.rs +++ b/crates/nu-command/src/filesystem/rm.rs @@ -428,10 +428,7 @@ fn rm( if let Err(e) = result { let msg = format!("Could not delete {:}: {e:}", f.to_string_lossy()); - Value::Error { - error: Box::new(ShellError::RemoveNotPossible(msg, span)), - span, - } + Value::error(ShellError::RemoveNotPossible(msg, span), span) } else if verbose { let msg = if interactive && !confirmed { "not deleted" @@ -439,35 +436,35 @@ fn rm( "deleted" }; let val = format!("{} {:}", msg, f.to_string_lossy()); - Value::String { val, span } + Value::string(val, span) } else { - Value::Nothing { span } + Value::nothing(span) } } else { let msg = format!("Cannot remove {:}. try --recursive", f.to_string_lossy()); - Value::Error { - error: Box::new(ShellError::GenericError( + Value::error( + ShellError::GenericError( msg, "cannot remove non-empty directory".into(), Some(span), None, Vec::new(), - )), + ), span, - } + ) } } else { let msg = format!("no such file or directory: {:}", f.to_string_lossy()); - Value::Error { - error: Box::new(ShellError::GenericError( + Value::error( + ShellError::GenericError( msg, "no such file or directory".into(), Some(span), None, Vec::new(), - )), + ), span, - } + ) } }) .filter(|x| !matches!(x.get_type(), Type::Nothing)) diff --git a/crates/nu-command/src/filesystem/watch.rs b/crates/nu-command/src/filesystem/watch.rs index 00eabce86..9374a0a22 100644 --- a/crates/nu-command/src/filesystem/watch.rs +++ b/crates/nu-command/src/filesystem/watch.rs @@ -213,7 +213,7 @@ impl Command for Watch { engine_state, stack, &block, - Value::Nothing { span: call.span() }.into_pipeline_data(), + Value::nothing(call.span()).into_pipeline_data(), call.redirect_stdout, call.redirect_stderr, ); diff --git a/crates/nu-command/src/filters/append.rs b/crates/nu-command/src/filters/append.rs index d9b9f7a8a..859067608 100644 --- a/crates/nu-command/src/filters/append.rs +++ b/crates/nu-command/src/filters/append.rs @@ -42,57 +42,57 @@ only unwrap the outer list, and leave the variable's contents untouched."# Example { example: "[0,1,2,3] | append 4", description: "Append one integer to a list", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(4), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "0 | append [1 2 3]", description: "Append a list to an item", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), Value::test_int(3), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: r#""a" | append ["b"] "#, description: "Append a list of string to a string", - result: Some(Value::List { - vals: vec![Value::test_string("a"), Value::test_string("b")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("a"), Value::test_string("b")], + Span::test_data(), + )), }, Example { example: "[0,1] | append [2,3,4]", description: "Append three integer items", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(4), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[0,1] | append [2,nu,4,shell]", description: "Append integers and strings", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), @@ -100,8 +100,8 @@ only unwrap the outer list, and leave the variable's contents untouched."# Value::test_int(4), Value::test_string("shell"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -128,8 +128,7 @@ only unwrap the outer list, and leave the variable's contents untouched."# fn process_value(val: Value) -> Vec { match val { Value::List { - vals: input_vals, - span: _, + vals: input_vals, .. } => { let mut output = vec![]; for input_val in input_vals { diff --git a/crates/nu-command/src/filters/columns.rs b/crates/nu-command/src/filters/columns.rs index 3bcc359c3..09b3d8be0 100644 --- a/crates/nu-command/src/filters/columns.rs +++ b/crates/nu-command/src/filters/columns.rs @@ -36,22 +36,22 @@ impl Command for Columns { Example { example: "{ acronym:PWD, meaning:'Print Working Directory' } | columns", description: "Get the columns from the record", - result: Some(Value::List { - vals: vec![Value::test_string("acronym"), Value::test_string("meaning")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("acronym"), Value::test_string("meaning")], + Span::test_data(), + )), }, Example { example: "[[name,age,grade]; [bill,20,a]] | columns", description: "Get the columns from the table", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("name"), Value::test_string("age"), Value::test_string("grade"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[[name,age,grade]; [bill,20,a]] | columns | first", @@ -87,30 +87,57 @@ fn getcol( let metadata = input.metadata(); match input { PipelineData::Empty => Ok(PipelineData::Empty), - PipelineData::Value( - Value::List { - vals: input_vals, - span, - }, - .., - ) => { - let input_cols = get_columns(&input_vals); - Ok(input_cols - .into_iter() - .map(move |x| Value::String { val: x, span }) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) - } - PipelineData::Value(Value::CustomValue { val, span }, ..) => { - // TODO: should we get CustomValue to expose columns in a more efficient way? - // Would be nice to be able to get columns without generating the whole value - let input_as_base_value = val.to_base_value(span)?; - let input_cols = get_columns(&[input_as_base_value]); - Ok(input_cols - .into_iter() - .map(move |x| Value::String { val: x, span }) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) + PipelineData::Value(v, ..) => { + let span = v.span(); + match v { + Value::List { + vals: input_vals, .. + } => { + let input_cols = get_columns(&input_vals); + Ok(input_cols + .into_iter() + .map(move |x| Value::string(x, span)) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) + } + Value::CustomValue { val, .. } => { + // TODO: should we get CustomValue to expose columns in a more efficient way? + // Would be nice to be able to get columns without generating the whole value + let input_as_base_value = val.to_base_value(span)?; + let input_cols = get_columns(&[input_as_base_value]); + Ok(input_cols + .into_iter() + .map(move |x| Value::string(x, span)) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) + } + Value::LazyRecord { val, .. } => { + Ok({ + // Unfortunate casualty to LazyRecord's column_names not generating 'static strs + let cols: Vec<_> = + val.column_names().iter().map(|s| s.to_string()).collect(); + + cols.into_iter() + .map(move |x| Value::string(x, head)) + .into_pipeline_data(ctrlc) + .set_metadata(metadata) + }) + } + Value::Record { val, .. } => Ok(val + .cols + .into_iter() + .map(move |x| Value::string(x, head)) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)), + // Propagate errors + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "record or table".into(), + wrong_type: other.get_type().to_string(), + dst_span: head, + src_span: other.span(), + }), + } } PipelineData::ListStream(stream, ..) => { let v: Vec<_> = stream.into_iter().collect(); @@ -118,33 +145,10 @@ fn getcol( Ok(input_cols .into_iter() - .map(move |x| Value::String { val: x, span: head }) + .map(move |x| Value::string(x, head)) .into_pipeline_data(ctrlc) .set_metadata(metadata)) } - PipelineData::Value(Value::LazyRecord { val, .. }, ..) => Ok({ - // Unfortunate casualty to LazyRecord's column_names not generating 'static strs - let cols: Vec<_> = val.column_names().iter().map(|s| s.to_string()).collect(); - - cols.into_iter() - .map(move |x| Value::String { val: x, span: head }) - .into_pipeline_data(ctrlc) - .set_metadata(metadata) - }), - PipelineData::Value(Value::Record { val, .. }, ..) => Ok(val - .cols - .into_iter() - .map(move |x| Value::String { val: x, span: head }) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)), - // Propagate errors - PipelineData::Value(Value::Error { error, .. }, ..) => Err(*error), - PipelineData::Value(other, ..) => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "record or table".into(), - wrong_type: other.get_type().to_string(), - dst_span: head, - src_span: other.span(), - }), PipelineData::ExternalStream { .. } => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "record or table".into(), wrong_type: "raw data".into(), diff --git a/crates/nu-command/src/filters/compact.rs b/crates/nu-command/src/filters/compact.rs index 2b750ff73..4f71a2533 100644 --- a/crates/nu-command/src/filters/compact.rs +++ b/crates/nu-command/src/filters/compact.rs @@ -54,29 +54,26 @@ impl Command for Compact { Example { description: "Filter out all records where 'Hello' is null (returns nothing)", example: r#"[["Hello" "World"]; [null 3]] | compact Hello"#, - result: Some(Value::List { - vals: vec![], - span: Span::test_data(), - }), + result: Some(Value::list(vec![], Span::test_data())), }, Example { description: "Filter out all records where 'World' is null (Returns the table)", example: r#"[["Hello" "World"]; [null 3]] | compact World"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["Hello".into(), "World".into()], vals: vec![Value::nothing(Span::test_data()), Value::test_int(3)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Filter out all instances of nothing from a list (Returns [1,2])", example: r#"[1, null, 2] | compact"#, - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/default.rs b/crates/nu-command/src/filters/default.rs index 72c4c7a6a..6bb194d97 100644 --- a/crates/nu-command/src/filters/default.rs +++ b/crates/nu-command/src/filters/default.rs @@ -57,15 +57,15 @@ impl Command for Default { Example { description: "Replace the `null` value in a list", example: "[1, 2, null, 4] | default 3", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(4), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -84,31 +84,33 @@ fn default( if let Some(column) = column { input.map( - move |item| match item { - Value::Record { - val: mut record, - span, - } => { - let mut idx = 0; - let mut found = false; + move |item| { + let span = item.span(); + match item { + Value::Record { + val: mut record, .. + } => { + let mut idx = 0; + let mut found = false; - while idx < record.len() { - if record.cols[idx] == column.item { - found = true; - if matches!(record.vals[idx], Value::Nothing { .. }) { - record.vals[idx] = value.clone(); + while idx < record.len() { + if record.cols[idx] == column.item { + found = true; + if matches!(record.vals[idx], Value::Nothing { .. }) { + record.vals[idx] = value.clone(); + } } + idx += 1; } - idx += 1; - } - if !found { - record.push(column.item.clone(), value.clone()); - } + if !found { + record.push(column.item.clone(), value.clone()); + } - Value::record(record, span) + Value::record(record, span) + } + _ => item, } - _ => item, }, ctrlc, ) diff --git a/crates/nu-command/src/filters/drop/column.rs b/crates/nu-command/src/filters/drop/column.rs index 9532ca3b2..022f4178f 100644 --- a/crates/nu-command/src/filters/drop/column.rs +++ b/crates/nu-command/src/filters/drop/column.rs @@ -64,8 +64,8 @@ impl Command for DropColumn { vec![Example { description: "Remove the last column of a table", example: "[[lib, extension]; [nu-lib, rs] [nu-core, rb]] | drop column", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["lib".into()], vals: vec![Value::test_string("nu-lib")], @@ -75,8 +75,8 @@ impl Command for DropColumn { vals: vec![Value::test_string("nu-core")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } @@ -90,32 +90,6 @@ fn dropcol( let mut keep_columns = vec![]; match input { - PipelineData::Value( - Value::List { - vals: input_vals, - span, - }, - .., - ) => { - let mut output = vec![]; - let input_cols = get_input_cols(input_vals.clone()); - let kc = get_keep_columns(input_cols, columns); - keep_columns = get_cellpath_columns(kc, span); - - for input_val in input_vals { - let mut record = Record::new(); - - for path in &keep_columns { - let fetcher = input_val.clone().follow_cell_path(&path.members, false)?; - record.push(path.into_string(), fetcher); - } - output.push(Value::record(record, span)) - } - - Ok(output - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) - } PipelineData::ListStream(stream, ..) => { let mut output = vec![]; @@ -139,14 +113,39 @@ fn dropcol( .into_pipeline_data(engine_state.ctrlc.clone())) } PipelineData::Value(v, ..) => { - let mut record = Record::new(); + let val_span = v.span(); + if let Value::List { + vals: input_vals, .. + } = v + { + let mut output = vec![]; + let input_cols = get_input_cols(input_vals.clone()); + let kc = get_keep_columns(input_cols, columns); + keep_columns = get_cellpath_columns(kc, val_span); - for cell_path in &keep_columns { - let result = v.clone().follow_cell_path(&cell_path.members, false)?; - record.push(cell_path.into_string(), result); + for input_val in input_vals { + let mut record = Record::new(); + + for path in &keep_columns { + let fetcher = input_val.clone().follow_cell_path(&path.members, false)?; + record.push(path.into_string(), fetcher); + } + output.push(Value::record(record, val_span)) + } + + Ok(output + .into_iter() + .into_pipeline_data(engine_state.ctrlc.clone())) + } else { + let mut record = Record::new(); + + for cell_path in &keep_columns { + let result = v.clone().follow_cell_path(&cell_path.members, false)?; + record.push(cell_path.into_string(), result); + } + + Ok(Value::record(record, span).into_pipeline_data()) } - - Ok(Value::record(record, span).into_pipeline_data()) } x => Ok(x), } @@ -163,10 +162,7 @@ fn get_input_cols(input: Vec) -> Vec { fn get_cellpath_columns(keep_cols: Vec, span: Span) -> Vec { let mut output = vec![]; for keep_col in keep_cols { - let val = Value::String { - val: keep_col, - span, - }; + let val = Value::string(keep_col, span); let cell_path = match CellPath::from_value(&val) { Ok(v) => v, Err(_) => return vec![], diff --git a/crates/nu-command/src/filters/drop/drop_.rs b/crates/nu-command/src/filters/drop/drop_.rs index 9c7a32b57..0fa9e1d0c 100644 --- a/crates/nu-command/src/filters/drop/drop_.rs +++ b/crates/nu-command/src/filters/drop/drop_.rs @@ -41,42 +41,42 @@ impl Command for Drop { Example { example: "[0,1,2,3] | drop", description: "Remove the last item of a list", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )), }, Example { example: "[0,1,2,3] | drop 0", description: "Remove zero item of a list", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), Value::test_int(3), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[0,1,2,3] | drop 2", description: "Remove the last two items of a list", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(1)], + Span::test_data(), + )), }, Example { description: "Remove the last row in a table", example: "[[a, b]; [1, 2] [3, 4]] | drop 1", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![Value::test_int(1), Value::test_int(2)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/drop/nth.rs b/crates/nu-command/src/filters/drop/nth.rs index a0e6ccd32..d6317cf11 100644 --- a/crates/nu-command/src/filters/drop/nth.rs +++ b/crates/nu-command/src/filters/drop/nth.rs @@ -44,58 +44,55 @@ impl Command for DropNth { Example { example: "[sam,sarah,2,3,4,5] | drop nth 0 1 2", description: "Drop the first, second, and third row", - result: Some(Value::List { - vals: vec![Value::test_int(3), Value::test_int(4), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(3), Value::test_int(4), Value::test_int(5)], + Span::test_data(), + )), }, Example { example: "[0,1,2,3,4,5] | drop nth 0 1 2", description: "Drop the first, second, and third row", - result: Some(Value::List { - vals: vec![Value::test_int(3), Value::test_int(4), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(3), Value::test_int(4), Value::test_int(5)], + Span::test_data(), + )), }, Example { example: "[0,1,2,3,4,5] | drop nth 0 2 4", description: "Drop rows 0 2 4", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)], + Span::test_data(), + )), }, Example { example: "[0,1,2,3,4,5] | drop nth 2 0 4", description: "Drop rows 2 0 4", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)], + Span::test_data(), + )), }, Example { description: "Drop range rows from second to fourth", example: "[first second third fourth fifth] | drop nth (1..3)", - result: Some(Value::List { - vals: vec![Value::test_string("first"), Value::test_string("fifth")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("first"), Value::test_string("fifth")], + Span::test_data(), + )), }, Example { example: "[0,1,2,3,4,5] | drop nth 1..", description: "Drop all rows except first row", - result: Some(Value::List { - vals: vec![Value::test_int(0)], - span: Span::test_data(), - }), + result: Some(Value::list(vec![Value::test_int(0)], Span::test_data())), }, Example { example: "[0,1,2,3,4,5] | drop nth 3..", description: "Drop rows 3,4,5", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )), }, ] } @@ -145,7 +142,7 @@ impl Command for DropNth { let mut to = to as usize; let from = from as usize; - if let PipelineData::Value(Value::List { ref vals, span: _ }, _) = input { + if let PipelineData::Value(Value::List { ref vals, .. }, _) = input { let max = from + vals.len() - 1; if to > max { to = max; diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index 2d029ff05..9d6b2907d 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -57,60 +57,50 @@ with 'transpose' first."# let stream_test_1 = vec![Value::test_int(2), Value::test_int(4), Value::test_int(6)]; let stream_test_2 = vec![ - Value::Nothing { - span: Span::test_data(), - }, + Value::nothing(Span::test_data()), Value::test_string("found 2!"), - Value::Nothing { - span: Span::test_data(), - }, + Value::nothing(Span::test_data()), ]; vec![ Example { example: "[1 2 3] | each {|e| 2 * $e }", description: "Multiplies elements in the list", - result: Some(Value::List { - vals: stream_test_1, - span: Span::test_data(), - }), + result: Some(Value::list(stream_test_1, Span::test_data())), }, Example { example: "{major:2, minor:1, patch:4} | values | each {|| into string }", description: "Produce a list of values in the record, converted to string", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("2"), Value::test_string("1"), Value::test_string("4"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: r#"[1 2 3 2] | each {|e| if $e == 2 { "two" } }"#, description: "Produce a list that has \"two\" for each 2 in the input", - result: Some(Value::List { - vals: vec![Value::test_string("two"), Value::test_string("two")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("two"), Value::test_string("two")], + Span::test_data(), + )), }, Example { example: r#"[1 2 3] | enumerate | each {|e| if $e.item == 2 { $"found 2 at ($e.index)!"} }"#, description: "Iterate over each element, producing a list showing indexes of any 2s", - result: Some(Value::List { - vals: vec![Value::test_string("found 2 at 1!")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("found 2 at 1!")], + Span::test_data(), + )), }, Example { example: r#"[1 2 3] | each --keep-empty {|e| if $e == 2 { "found 2!"} }"#, description: "Iterate over each element, keeping null results", - result: Some(Value::List { - vals: stream_test_2, - span: Span::test_data(), - }), + result: Some(Value::list(stream_test_2, Span::test_data())), }, ] } @@ -171,10 +161,7 @@ with 'transpose' first."# Err(ShellError::Break(_)) => None, Err(error) => { let error = chain_error_with_input(error, x_is_error, input_span); - Some(Value::Error { - error: Box::new(error), - span: input_span, - }) + Some(Value::error(error, input_span)) } } }) @@ -195,12 +182,7 @@ with 'transpose' first."# Ok(x) => x, Err(ShellError::Continue(v)) => return Some(Value::nothing(v)), Err(ShellError::Break(_)) => return None, - Err(err) => { - return Some(Value::Error { - error: Box::new(err), - span, - }) - } + Err(err) => return Some(Value::error(err, span)), }; if let Some(var) = block.signature.get_positional(0) { @@ -224,12 +206,8 @@ with 'transpose' first."# Err(ShellError::Continue(v)) => Some(Value::nothing(v)), Err(ShellError::Break(_)) => None, Err(error) => { - let error = - Box::new(chain_error_with_input(error, x_is_error, input_span)); - Some(Value::Error { - error, - span: input_span, - }) + let error = chain_error_with_input(error, x_is_error, input_span); + Some(Value::error(error, input_span)) } } }) diff --git a/crates/nu-command/src/filters/enumerate.rs b/crates/nu-command/src/filters/enumerate.rs index 271584944..08c6da1c1 100644 --- a/crates/nu-command/src/filters/enumerate.rs +++ b/crates/nu-command/src/filters/enumerate.rs @@ -31,8 +31,8 @@ impl Command for Enumerate { vec![Example { description: "Add an index to each element of a list", example: r#"[a, b, c] | enumerate "#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["index".into(), "item".into()], vals: vec![Value::test_int(0), Value::test_string("a")], @@ -46,8 +46,8 @@ impl Command for Enumerate { vals: vec![Value::test_int(2), Value::test_string("c")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } diff --git a/crates/nu-command/src/filters/every.rs b/crates/nu-command/src/filters/every.rs index 5ddd7919b..77a0c282e 100644 --- a/crates/nu-command/src/filters/every.rs +++ b/crates/nu-command/src/filters/every.rs @@ -43,18 +43,18 @@ impl Command for Every { Example { example: "[1 2 3 4 5] | every 2", description: "Get every second row", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(3), Value::test_int(5)], + Span::test_data(), + )), }, Example { example: "[1 2 3 4 5] | every 2 --skip", description: "Skip every second row", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(4)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(4)], + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/filter.rs b/crates/nu-command/src/filters/filter.rs index 7d207bab2..1d6aafcca 100644 --- a/crates/nu-command/src/filters/filter.rs +++ b/crates/nu-command/src/filters/filter.rs @@ -101,10 +101,10 @@ a variable. On the other hand, the "row condition" syntax is not supported."# None } } - Err(error) => Some(Value::Error { - error: Box::new(chain_error_with_input(error, x.is_error(), x.span())), - span: x.span(), - }), + Err(error) => Some(Value::error( + chain_error_with_input(error, x.is_error(), x.span()), + x.span(), + )), } }) .into_pipeline_data(ctrlc)), @@ -120,12 +120,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# let x = match x { Ok(x) => x, - Err(err) => { - return Some(Value::Error { - error: Box::new(err), - span, - }) - } + Err(err) => return Some(Value::error(err, span)), }; if let Some(var) = block.signature.get_positional(0) { @@ -150,10 +145,10 @@ a variable. On the other hand, the "row condition" syntax is not supported."# None } } - Err(error) => Some(Value::Error { - error: Box::new(chain_error_with_input(error, x.is_error(), x.span())), - span: x.span(), - }), + Err(error) => Some(Value::error( + chain_error_with_input(error, x.is_error(), x.span()), + x.span(), + )), } }) .into_pipeline_data(ctrlc)), @@ -184,10 +179,10 @@ a variable. On the other hand, the "row condition" syntax is not supported."# None } } - Err(error) => Some(Value::Error { - error: Box::new(chain_error_with_input(error, x.is_error(), x.span())), - span: x.span(), - }), + Err(error) => Some(Value::error( + chain_error_with_input(error, x.is_error(), x.span()), + x.span(), + )), } .into_pipeline_data(ctrlc)) } @@ -200,57 +195,54 @@ a variable. On the other hand, the "row condition" syntax is not supported."# Example { description: "Filter items of a list according to a condition", example: "[1 2] | filter {|x| $x > 1}", - result: Some(Value::List { - vals: vec![Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list(vec![Value::test_int(2)], Span::test_data())), }, Example { description: "Filter rows of a table according to a condition", example: "[{a: 1} {a: 2}] | filter {|x| $x.a > 1}", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(2)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Filter rows of a table according to a stored condition", example: "let cond = {|x| $x.a > 1}; [{a: 1} {a: 2}] | filter $cond", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(2)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Filter items of a range according to a condition", example: "9..13 | filter {|el| $el mod 2 != 0}", - result: Some(Value::List { - vals: vec![Value::test_int(9), Value::test_int(11), Value::test_int(13)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(9), Value::test_int(11), Value::test_int(13)], + Span::test_data(), + )), }, Example { description: "List all numbers above 3, using an existing closure condition", example: "let a = {$in > 3}; [1, 2, 5, 6] | filter $a", result: None, // TODO: This should work - // result: Some(Value::List { - // vals: vec![ + // result: Some(Value::list( + // vec![ // Value::Int { // val: 5, - // span: Span::test_data(), + // Span::test_data(), // }, // Value::Int { // val: 6, // span: Span::test_data(), // }, // ], - // span: Span::test_data(), + // Span::test_data(), // }), }, ] diff --git a/crates/nu-command/src/filters/find.rs b/crates/nu-command/src/filters/find.rs index 1e0b10810..9cf4c4ab0 100644 --- a/crates/nu-command/src/filters/find.rs +++ b/crates/nu-command/src/filters/find.rs @@ -87,60 +87,60 @@ impl Command for Find { Example { description: "Search a number or a file size in a list of numbers", example: r#"[1 5 3kb 4 3Mb] | find 5 3kb"#, - result: Some(Value::List { - vals: vec![Value::test_int(5), Value::test_filesize(3000)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(5), Value::test_filesize(3000)], + Span::test_data(), + )), }, Example { description: "Search a char in a list of string", example: r#"[moe larry curly] | find l"#, - result: Some(Value::List { - vals: vec![Value::test_string("larry"), Value::test_string("curly")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("larry"), Value::test_string("curly")], + Span::test_data(), + )), }, Example { description: "Find using regex", example: r#"[abc bde arc abf] | find --regex "ab""#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("abc".to_string()), Value::test_string("abf".to_string()), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Find using regex case insensitive", example: r#"[aBc bde Arc abf] | find --regex "ab" -i"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("aBc".to_string()), Value::test_string("abf".to_string()), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Find value in records using regex", example: r#"[[version name]; ['0.1.0' nushell] ['0.1.1' fish] ['0.2.0' zsh]] | find -r "nu""#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["version".to_string(), "name".to_string()], vals: vec![ Value::test_string("0.1.0"), Value::test_string("nushell".to_string()), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Find inverted values in records using regex", example: r#"[[version name]; ['0.1.0' nushell] ['0.1.1' fish] ['0.2.0' zsh]] | find -r "nu" --invert"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["version".to_string(), "name".to_string()], vals: vec![ @@ -156,30 +156,30 @@ impl Command for Find { ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Find value in list using regex", example: r#"[["Larry", "Moe"], ["Victor", "Marina"]] | find -r "rr""#, - result: Some(Value::List { - vals: vec![Value::List { - vals: vec![Value::test_string("Larry"), Value::test_string("Moe")], - span: Span::test_data(), - }], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::list( + vec![Value::test_string("Larry"), Value::test_string("Moe")], + Span::test_data(), + )], + Span::test_data(), + )), }, Example { description: "Find inverted values in records using regex", example: r#"[["Larry", "Moe"], ["Victor", "Marina"]] | find -r "rr" --invert"#, - result: Some(Value::List { - vals: vec![Value::List { - vals: vec![Value::test_string("Victor"), Value::test_string("Marina")], - span: Span::test_data(), - }], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::list( + vec![Value::test_string("Victor"), Value::test_string("Marina")], + Span::test_data(), + )], + Span::test_data(), + )), }, Example { description: "Remove ANSI sequences from result", @@ -190,8 +190,8 @@ impl Command for Find { description: "Find and highlight text in specific columns", example: "[[col1 col2 col3]; [moe larry curly] [larry curly moe]] | find moe -c [col1]", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["col1".to_string(), "col2".to_string(), "col3".to_string()], vals: vec![ Value::test_string( @@ -202,8 +202,8 @@ impl Command for Find { Value::test_string("curly".to_string()), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -224,7 +224,7 @@ impl Command for Find { if let Some(regex) = regex { find_with_regex(regex, engine_state, stack, call, input) } else { - let input = split_string_if_multiline(input); + let input = split_string_if_multiline(input, call.head); find_with_rest_and_highlight(engine_state, stack, call, input) } } @@ -331,10 +331,7 @@ fn highlight_terms_in_record_with_search_columns( highlight_search_string(&val_str, term_str, &string_style, &highlight_style) .unwrap_or_else(|_| string_style.paint(term_str).to_string()); - Value::String { - val: highlighted_str, - span, - } + Value::string(highlighted_str, span) }) .map(|v| v.unwrap_or_else(|v| v)); @@ -388,17 +385,20 @@ fn find_with_rest_and_highlight( PipelineData::Empty => Ok(PipelineData::Empty), PipelineData::Value(_, _) => input .map( - move |mut x| match &mut x { - Value::Record { val, span } => highlight_terms_in_record_with_search_columns( - &cols_to_search_in_map, - val, - *span, - &config, - &terms, - string_style, - highlight_style, - ), - _ => x, + move |mut x| { + let span = x.span(); + match &mut x { + Value::Record { val, .. } => highlight_terms_in_record_with_search_columns( + &cols_to_search_in_map, + val, + span, + &config, + &terms, + string_style, + highlight_style, + ), + _ => x, + } }, ctrlc.clone(), )? @@ -417,17 +417,20 @@ fn find_with_rest_and_highlight( ), PipelineData::ListStream(stream, meta) => Ok(ListStream::from_stream( stream - .map(move |mut x| match &mut x { - Value::Record { val, span } => highlight_terms_in_record_with_search_columns( - &cols_to_search_in_map, - val, - *span, - &config, - &terms, - string_style, - highlight_style, - ), - _ => x, + .map(move |mut x| { + let span = x.span(); + match &mut x { + Value::Record { val, .. } => highlight_terms_in_record_with_search_columns( + &cols_to_search_in_map, + val, + span, + &config, + &terms, + string_style, + highlight_style, + ), + _ => x, + } }) .filter(move |value| { value_should_be_printed( @@ -451,42 +454,45 @@ fn find_with_rest_and_highlight( let mut output: Vec = vec![]; for filter_val in stream { match filter_val { - Ok(value) => match value { - Value::String { val, span } => { - let split_char = if val.contains("\r\n") { "\r\n" } else { "\n" }; + Ok(value) => { + let span = value.span(); + match value { + Value::String { val, .. } => { + let split_char = if val.contains("\r\n") { "\r\n" } else { "\n" }; - for line in val.split(split_char) { - for term in lower_terms.iter() { - let term_str = term.into_string("", &filter_config); - let lower_val = line.to_lowercase(); - if lower_val - .contains(&term.into_string("", &config).to_lowercase()) - { - output.push(Value::String { - val: highlight_search_string( - line, - &term_str, - &string_style, - &highlight_style, - )?, - span, - }) + for line in val.split(split_char) { + for term in lower_terms.iter() { + let term_str = term.into_string("", &filter_config); + let lower_val = line.to_lowercase(); + if lower_val + .contains(&term.into_string("", &config).to_lowercase()) + { + output.push(Value::string( + highlight_search_string( + line, + &term_str, + &string_style, + &highlight_style, + )?, + span, + )) + } } } } + // Propagate errors by explicitly matching them before the final case. + Value::Error { error, .. } => return Err(*error), + other => { + return Err(ShellError::UnsupportedInput( + "unsupported type from raw stream".into(), + format!("input: {:?}", other.get_type()), + span, + // This line requires the Value::Error match above. + other.span(), + )); + } } - // Propagate errors by explicitly matching them before the final case. - Value::Error { error, .. } => return Err(*error), - other => { - return Err(ShellError::UnsupportedInput( - "unsupported type from raw stream".into(), - format!("input: {:?}", other.get_type()), - span, - // This line requires the Value::Error match above. - other.span(), - )); - } - }, + } // Propagate any errors that were in the stream Err(e) => return Err(e), }; @@ -593,21 +599,17 @@ mod tests { } } -fn split_string_if_multiline(input: PipelineData) -> PipelineData { +fn split_string_if_multiline(input: PipelineData, head_span: Span) -> PipelineData { + let span = input.span().unwrap_or(head_span); match input { - PipelineData::Value(Value::String { ref val, span }, _) => { + PipelineData::Value(Value::String { ref val, .. }, _) => { if val.contains('\n') { - Value::List { - vals: { - val.lines() - .map(|s| Value::String { - val: s.to_string(), - span, - }) - .collect() - }, + Value::list( + val.lines() + .map(|s| Value::string(s.to_string(), span)) + .collect(), span, - } + ) .into_pipeline_data() .set_metadata(input.metadata()) } else { diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs index 5cf700e88..04138bcf7 100644 --- a/crates/nu-command/src/filters/first.rs +++ b/crates/nu-command/src/filters/first.rs @@ -68,18 +68,15 @@ impl Command for First { Example { description: "Return the first 2 items of a list/table", example: "[1 2 3] | first 2", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )), }, Example { description: "Return the first 2 bytes of a binary value", example: "0x[01 23 45] | first 2", - result: Some(Value::Binary { - val: vec![0x01, 0x23], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x01, 0x23], Span::test_data())), }, ] } @@ -115,63 +112,60 @@ fn first_helper( } match input { - PipelineData::Value(val, _) => match val { - Value::List { vals, .. } => { - if return_single_element { - if vals.is_empty() { - Err(ShellError::AccessEmptyContent { span: head }) + PipelineData::Value(val, _) => { + let span = val.span(); + match val { + Value::List { vals, .. } => { + if return_single_element { + if vals.is_empty() { + Err(ShellError::AccessEmptyContent { span: head }) + } else { + Ok(vals[0].clone().into_pipeline_data()) + } } else { - Ok(vals[0].clone().into_pipeline_data()) + Ok(vals + .into_iter() + .take(rows_desired) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) } - } else { - Ok(vals - .into_iter() - .take(rows_desired) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) } - } - Value::Binary { val, span } => { - if return_single_element { - if val.is_empty() { - Err(ShellError::AccessEmptyContent { span: head }) + Value::Binary { val, .. } => { + if return_single_element { + if val.is_empty() { + Err(ShellError::AccessEmptyContent { span: head }) + } else { + Ok(PipelineData::Value( + Value::int(val[0] as i64, span), + metadata, + )) + } } else { - Ok(PipelineData::Value( - Value::Int { - val: val[0] as i64, - span, - }, - metadata, - )) + let slice: Vec = val.into_iter().take(rows_desired).collect(); + Ok(PipelineData::Value(Value::binary(slice, span), metadata)) } - } else { - let slice: Vec = val.into_iter().take(rows_desired).collect(); - Ok(PipelineData::Value( - Value::Binary { val: slice, span }, - metadata, - )) } - } - Value::Range { val, .. } => { - if return_single_element { - Ok(val.from.into_pipeline_data()) - } else { - Ok(val - .into_range_iter(ctrlc.clone())? - .take(rows_desired) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) + Value::Range { val, .. } => { + if return_single_element { + Ok(val.from.into_pipeline_data()) + } else { + Ok(val + .into_range_iter(ctrlc.clone())? + .take(rows_desired) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) + } } + // Propagate errors by explicitly matching them before the final case. + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "list, binary or range".into(), + wrong_type: other.get_type().to_string(), + dst_span: head, + src_span: other.span(), + }), } - // Propagate errors by explicitly matching them before the final case. - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "list, binary or range".into(), - wrong_type: other.get_type().to_string(), - dst_span: head, - src_span: other.span(), - }), - }, + } PipelineData::ListStream(mut ls, metadata) => { if return_single_element { if let Some(v) = ls.next() { diff --git a/crates/nu-command/src/filters/flatten.rs b/crates/nu-command/src/filters/flatten.rs index 7f23fc442..fa1977afa 100644 --- a/crates/nu-command/src/filters/flatten.rs +++ b/crates/nu-command/src/filters/flatten.rs @@ -52,8 +52,8 @@ impl Command for Flatten { Example { description: "flatten a table", example: "[[N, u, s, h, e, l, l]] | flatten ", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("N"), Value::test_string("u"), Value::test_string("s"), @@ -61,8 +61,8 @@ impl Command for Flatten { Value::test_string("e"), Value::test_string("l"), Value::test_string("l")], - span: Span::test_data() - }) + Span::test_data() + )) }, Example { description: "flatten a table, get the first item", @@ -82,17 +82,17 @@ impl Command for Flatten { Example { description: "Flatten inner table", example: "{ a: b, d: [ 1 2 3 4 ], e: [ 4 3 ] } | flatten d --all", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string(), "d".to_string(), "e".to_string()], vals: vec![ Value::test_string("b"), Value::test_int(1), - Value::List { - vals: vec![Value::test_int(4), Value::test_int(3)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(4), Value::test_int(3)], + Span::test_data(), + ), ], }), Value::test_record(Record { @@ -100,10 +100,10 @@ impl Command for Flatten { vals: vec![ Value::test_string("b"), Value::test_int(2), - Value::List { - vals: vec![Value::test_int(4), Value::test_int(3)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(4), Value::test_int(3)], + Span::test_data(), + ), ], }), Value::test_record(Record { @@ -111,10 +111,10 @@ impl Command for Flatten { vals: vec![ Value::test_string("b"), Value::test_int(3), - Value::List { - vals: vec![Value::test_int(4), Value::test_int(3)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(4), Value::test_int(3)], + Span::test_data(), + ), ], }), Value::test_record(Record { @@ -122,15 +122,15 @@ impl Command for Flatten { vals: vec![ Value::test_string("b"), Value::test_int(4), - Value::List { - vals: vec![Value::test_int(4), Value::test_int(3)], - span: Span::test_data() - } + Value::list( + vec![Value::test_int(4), Value::test_int(3)], + Span::test_data() + ) ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), } ] } @@ -187,15 +187,15 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) -> // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => return vec![item.clone()], other => { - return vec![Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + return vec![Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "record".into(), wrong_type: other.get_type().to_string(), dst_span: name_tag, src_span: other.span(), - }), - span: name_tag, - }]; + }, + name_tag, + )]; } }; @@ -204,6 +204,7 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) -> for (column_index, (column, value)) in record.iter().enumerate() { let column_requested = columns.iter().find(|c| c.into_string() == *column); let need_flatten = { columns.is_empty() || column_requested.is_some() }; + let span = value.span(); match value { Value::Record { val, .. } => { @@ -221,14 +222,14 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) -> out.insert(column.to_string(), value.clone()); } } - Value::List { vals, span } if all && vals.iter().all(|f| f.as_record().is_ok()) => { + Value::List { vals, .. } if all && vals.iter().all(|f| f.as_record().is_ok()) => { if need_flatten && inner_table.is_some() { - return vec![Value::Error{ error: Box::new(ShellError::UnsupportedInput( + return vec![Value::error( ShellError::UnsupportedInput( "can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(), "value originates from here".into(), s, - *span - )), span: *span} + span + ), span) ]; } // it's a table (a list of record, we can flatten inner record) @@ -257,15 +258,15 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) -> out.insert(column.to_string(), value.clone()); } } - Value::List { vals: values, span } => { + Value::List { vals: values, .. } => { if need_flatten && inner_table.is_some() { - return vec![Value::Error{ error: Box::new(ShellError::UnsupportedInput( - "can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(), - "value originates from here".into(), - s, - *span - )), span: *span} - ]; + return vec![Value::error( ShellError::UnsupportedInput( + "can only flatten one inner list at a time. tried flattening more than one column with inner lists... but is flattened already".to_string(), + "value originates from here".into(), + s, + span + ), span) + ]; } if !columns.is_empty() { @@ -370,7 +371,7 @@ fn flat_value(columns: &[CellPath], item: &Value, name_tag: Span, all: bool) -> } expanded } else if item.as_list().is_ok() { - if let Value::List { vals, span: _ } = item { + if let Value::List { vals, .. } = item { vals.to_vec() } else { vec![] diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index f9eb66e26..938861e0a 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -106,10 +106,10 @@ If multiple cell paths are given, this will produce a list of values."# Example { description: "Get a column from a table", example: "[{A: A0}] | get A", - result: Some(Value::List { - vals: vec![Value::test_string("A0")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("A0")], + Span::test_data(), + )), }, Example { description: "Get a cell from a table", diff --git a/crates/nu-command/src/filters/group.rs b/crates/nu-command/src/filters/group.rs index 3f4403cc0..b8c23f84b 100644 --- a/crates/nu-command/src/filters/group.rs +++ b/crates/nu-command/src/filters/group.rs @@ -34,23 +34,20 @@ impl Command for Group { fn examples(&self) -> Vec { let stream_test_1 = vec![ - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(3), Value::test_int(4)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(3), Value::test_int(4)], + Span::test_data(), + ), ]; vec![Example { example: "[1 2 3 4] | group 2", description: "Group the a list by pairs", - result: Some(Value::List { - vals: stream_test_1, - span: Span::test_data(), - }), + result: Some(Value::list(stream_test_1, Span::test_data())), }] } @@ -112,10 +109,7 @@ impl Iterator for EachGroupIterator { return None; } - Some(Value::List { - vals: group, - span: self.span, - }) + Some(Value::list(group, self.span)) } } diff --git a/crates/nu-command/src/filters/group_by.rs b/crates/nu-command/src/filters/group_by.rs index 1ca15b2da..bc4383dbd 100644 --- a/crates/nu-command/src/filters/group_by.rs +++ b/crates/nu-command/src/filters/group_by.rs @@ -71,17 +71,17 @@ impl Command for GroupBy { result: Some(Value::test_record(Record { cols: vec!["txt".to_string(), "csv".to_string()], vals: vec![ - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_string("foo.txt"), Value::test_string("baz.txt"), ], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_string("bar.csv")], - span: Span::test_data(), - }, + Span::test_data(), + ), + Value::list( + vec![Value::test_string("bar.csv")], + Span::test_data(), + ), ], })), }, @@ -92,23 +92,23 @@ impl Command for GroupBy { result: Some(Value::test_record(Record { cols: vec!["1".to_string(), "3".to_string(), "2".to_string()], vals: vec![ - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_string("1"), Value::test_string("1"), Value::test_string("1"), Value::test_string("1"), ], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_string("3"), Value::test_string("3")], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_string("2")], - span: Span::test_data(), - }, + Span::test_data(), + ), + Value::list( + vec![Value::test_string("3"), Value::test_string("3")], + Span::test_data(), + ), + Value::list( + vec![Value::test_string("2")], + Span::test_data(), + ), ], })), }, @@ -138,18 +138,24 @@ pub fn group_by( } let group_value = match grouper { - Some(Value::CellPath { val, span }) => group_cell_path(val, values, span)?, - Some(Value::Block { .. }) | Some(Value::Closure { .. }) => { - let block: Option = call.opt(engine_state, stack, 0)?; - group_closure(&values, span, block, stack, engine_state, call)? + Some(v) => { + let span = v.span(); + match v { + Value::CellPath { val, .. } => group_cell_path(val, values, span)?, + Value::Block { .. } | Value::Closure { .. } => { + let block: Option = call.opt(engine_state, stack, 0)?; + group_closure(&values, span, block, stack, engine_state, call)? + } + + _ => { + return Err(ShellError::TypeMismatch { + err_message: "unsupported grouper type".to_string(), + span, + }) + } + } } None => group_no_grouper(values, span)?, - _ => { - return Err(ShellError::TypeMismatch { - err_message: "unsupported grouper type".to_string(), - span, - }) - } }; Ok(PipelineData::Value(group_value, None)) @@ -213,10 +219,7 @@ fn group_closure( ) -> Result { let error_key = "error"; let mut keys: Vec> = vec![]; - let value_list = Value::List { - vals: values.clone(), - span, - }; + let value_list = Value::list(values.clone(), span); for value in values { if let Some(capture_block) = &block { diff --git a/crates/nu-command/src/filters/headers.rs b/crates/nu-command/src/filters/headers.rs index b824c3b5d..1a8372652 100644 --- a/crates/nu-command/src/filters/headers.rs +++ b/crates/nu-command/src/filters/headers.rs @@ -36,8 +36,8 @@ impl Command for Headers { Example { description: "Sets the column names for a table created by `split column`", example: r#""a b c|1 2 3" | split row "|" | split column " " | headers"#, - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: columns.clone(), vals: vec![ Value::test_string("1"), @@ -45,14 +45,14 @@ impl Command for Headers { Value::test_string("3"), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Columns which don't have data in their first row are removed", example: r#""a b c|1 2 3|1 2 3 4" | split row "|" | split column " " | headers"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: columns.clone(), vals: vec![ @@ -70,8 +70,8 @@ impl Command for Headers { ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -98,8 +98,9 @@ fn replace_headers( old_headers: &[String], new_headers: &[String], ) -> Result { + let span = value.span(); match value { - Value::Record { val, span } => Ok(Value::record( + Value::Record { val, .. } => Ok(Value::record( val.into_iter() .filter_map(|(col, val)| { old_headers @@ -110,14 +111,14 @@ fn replace_headers( .collect(), span, )), - Value::List { vals, span } => { + Value::List { vals, .. } => { let vals = vals .into_iter() .skip(1) .map(|value| replace_headers(value, old_headers, new_headers)) .collect::, ShellError>>()?; - Ok(Value::List { vals, span }) + Ok(Value::list(vals, span)) } _ => Err(ShellError::TypeMismatch { err_message: "record".to_string(), @@ -129,11 +130,11 @@ fn replace_headers( fn is_valid_header(value: &Value) -> bool { matches!( value, - Value::Nothing { span: _ } - | Value::String { val: _, span: _ } - | Value::Bool { val: _, span: _ } - | Value::Float { val: _, span: _ } - | Value::Int { val: _, span: _ } + Value::Nothing { .. } + | Value::String { val: _, .. } + | Value::Bool { val: _, .. } + | Value::Float { val: _, .. } + | Value::Int { val: _, .. } ) } @@ -141,6 +142,7 @@ fn extract_headers( value: &Value, config: &Config, ) -> Result<(Vec, Vec), ShellError> { + let span = value.span(); match value { Value::Record { val: record, .. } => { for v in &record.vals { @@ -170,7 +172,7 @@ fn extract_headers( Ok((old_headers, new_headers)) } - Value::List { vals, span } => vals + Value::List { vals, .. } => vals .iter() .map(|value| extract_headers(value, config)) .next() @@ -178,7 +180,7 @@ fn extract_headers( ShellError::GenericError( "Found empty list".to_string(), "unable to extract headers".to_string(), - Some(*span), + Some(span), None, Vec::new(), ) diff --git a/crates/nu-command/src/filters/insert.rs b/crates/nu-command/src/filters/insert.rs index 42a6dcf0e..4a7c8ecd9 100644 --- a/crates/nu-command/src/filters/insert.rs +++ b/crates/nu-command/src/filters/insert.rs @@ -72,19 +72,19 @@ impl Command for Insert { Example { description: "Insert a new column into a table, populating all rows", example: "[[project, lang]; ['Nushell', 'Rust']] | insert type 'shell'", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["project".into(), "lang".into(), "type".into()], vals: vec![Value::test_string("Nushell"), Value::test_string("Rust"), Value::test_string("shell")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Insert a column with values equal to their row index, plus the value of 'foo' in each row", example: "[[foo]; [7] [8] [9]] | enumerate | insert bar {|e| $e.item.foo + $e.index } | flatten", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list ( + vec![ Value::test_record(Record { cols: vec!["index".into(), "foo".into(), "bar".into()], vals: vec![ @@ -110,8 +110,8 @@ impl Command for Insert { ], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } @@ -173,18 +173,12 @@ fn insert( pd.into_value(span), span, ) { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } input } - Err(e) => Value::Error { - error: Box::new(e), - span, - }, + Err(e) => Value::error(e, span), } }, ctrlc, @@ -198,7 +192,7 @@ fn insert( if let Some(v) = input.next() { pre_elems.push(v); } else { - pre_elems.push(Value::Nothing { span }) + pre_elems.push(Value::nothing(span)) } } @@ -215,10 +209,7 @@ fn insert( if let Err(e) = input.insert_data_at_cell_path(&cell_path.members, replacement, span) { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } input diff --git a/crates/nu-command/src/filters/items.rs b/crates/nu-command/src/filters/items.rs index dc93a9f2a..619adee4a 100644 --- a/crates/nu-command/src/filters/items.rs +++ b/crates/nu-command/src/filters/items.rs @@ -87,10 +87,7 @@ impl Command for Items { Err(ShellError::Break(_)) => None, Err(error) => { let error = chain_error_with_input(error, false, input_span); - Some(Value::Error { - error: Box::new(error), - span, - }) + Some(Value::error(error, span)) } } }; @@ -129,13 +126,13 @@ impl Command for Items { example: "{ new: york, san: francisco } | items {|key, value| echo $'($key) ($value)' }", description: "Iterate over each key-value pair of a record", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("new york"), Value::test_string("san francisco"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } diff --git a/crates/nu-command/src/filters/join.rs b/crates/nu-command/src/filters/join.rs index d7643e568..d278f31d4 100644 --- a/crates/nu-command/src/filters/join.rs +++ b/crates/nu-command/src/filters/join.rs @@ -110,26 +110,13 @@ impl Command for Join { vec![Example { description: "Join two tables", example: "[{a: 1 b: 2}] | join [{a: 1 c: 3}] a", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["a".into(), "b".into(), "c".into()], - vals: vec![ - Value::Int { - val: 1, - span: Span::test_data(), - }, - Value::Int { - val: 2, - span: Span::test_data(), - }, - Value::Int { - val: 3, - span: Span::test_data(), - }, - ], + vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } @@ -253,7 +240,7 @@ fn join( span, ); } - Value::List { vals: result, span } + Value::list(result, span) } // Join rows of `this` (a nushell table) to rows of `other` (a lookup-table diff --git a/crates/nu-command/src/filters/last.rs b/crates/nu-command/src/filters/last.rs index d66f34df4..99ec89383 100644 --- a/crates/nu-command/src/filters/last.rs +++ b/crates/nu-command/src/filters/last.rs @@ -54,10 +54,10 @@ impl Command for Last { Example { example: "[1,2,3] | last 2", description: "Return the last 2 items of a list/table", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(3)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(3)], + Span::test_data(), + )), }, Example { example: "[1,2,3] | last", @@ -67,10 +67,7 @@ impl Command for Last { Example { example: "0x[01 23 45] | last 2", description: "Return the last 2 bytes of a binary value", - result: Some(Value::Binary { - val: vec![0x23, 0x45], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x23, 0x45], Span::test_data())), }, ] } @@ -129,55 +126,56 @@ impl Command for Last { Ok(buf.into_pipeline_data(ctrlc).set_metadata(metadata)) } } - PipelineData::Value(val, _) => match val { - Value::List { vals, .. } => { - if return_single_element { - if let Some(v) = vals.last() { - Ok(v.clone().into_pipeline_data()) + PipelineData::Value(val, _) => { + let val_span = val.span(); + + match val { + Value::List { vals, .. } => { + if return_single_element { + if let Some(v) = vals.last() { + Ok(v.clone().into_pipeline_data()) + } else { + Err(ShellError::AccessEmptyContent { span: head }) + } } else { - Err(ShellError::AccessEmptyContent { span: head }) + Ok(vals + .into_iter() + .rev() + .take(rows_desired) + .rev() + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) } - } else { - Ok(vals - .into_iter() - .rev() - .take(rows_desired) - .rev() - .into_pipeline_data(ctrlc) - .set_metadata(metadata)) } - } - Value::Binary { val, span } => { - if return_single_element { - if let Some(b) = val.last() { + Value::Binary { val, .. } => { + if return_single_element { + if let Some(b) = val.last() { + Ok(PipelineData::Value( + Value::int(*b as i64, val_span), + metadata, + )) + } else { + Err(ShellError::AccessEmptyContent { span: head }) + } + } else { + let slice: Vec = + val.into_iter().rev().take(rows_desired).rev().collect(); Ok(PipelineData::Value( - Value::Int { - val: *b as i64, - span, - }, + Value::binary(slice, val_span), metadata, )) - } else { - Err(ShellError::AccessEmptyContent { span: head }) } - } else { - let slice: Vec = - val.into_iter().rev().take(rows_desired).rev().collect(); - Ok(PipelineData::Value( - Value::Binary { val: slice, span }, - metadata, - )) } + // Propagate errors by explicitly matching them before the final case. + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "list, binary or range".into(), + wrong_type: other.get_type().to_string(), + dst_span: head, + src_span: other.span(), + }), } - // Propagate errors by explicitly matching them before the final case. - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "list, binary or range".into(), - wrong_type: other.get_type().to_string(), - dst_span: head, - src_span: other.span(), - }), - }, + } PipelineData::ExternalStream { span, .. } => { Err(ShellError::OnlySupportsThisInputType { exp_input_type: "list, binary or range".into(), diff --git a/crates/nu-command/src/filters/length.rs b/crates/nu-command/src/filters/length.rs index c1fb54c60..0103fb75c 100644 --- a/crates/nu-command/src/filters/length.rs +++ b/crates/nu-command/src/filters/length.rs @@ -56,13 +56,14 @@ impl Command for Length { } fn length_row(call: &Call, input: PipelineData) -> Result { + let span = input.span().unwrap_or(call.head); match input { PipelineData::Value(Value::Nothing { .. }, ..) => { Ok(Value::int(0, call.head).into_pipeline_data()) } // I added this here because input_output_type() wasn't catching a record // being sent in as input from echo. e.g. "echo {a:1 b:2} | length" - PipelineData::Value(Value::Record { span, .. }, ..) => { + PipelineData::Value(Value::Record { .. }, ..) => { Err(ShellError::OnlySupportsThisInputType { exp_input_type: "list, and table".into(), wrong_type: "record".into(), diff --git a/crates/nu-command/src/filters/lines.rs b/crates/nu-command/src/filters/lines.rs index 1335e2b11..19f071f7f 100644 --- a/crates/nu-command/src/filters/lines.rs +++ b/crates/nu-command/src/filters/lines.rs @@ -27,7 +27,6 @@ impl Command for Lines { .switch("skip-empty", "skip empty lines", Some('s')) .category(Category::Filters) } - fn run( &self, engine_state: &EngineState, @@ -42,12 +41,13 @@ impl Command for Lines { // match \r\n or \n static LINE_BREAK_REGEX: Lazy = Lazy::new(|| Regex::new(r"\r\n|\n").expect("unable to compile regex")); + let span = input.span().unwrap_or(call.head); match input { #[allow(clippy::needless_collect)] // Collect is needed because the string may not live long enough for // the Rc structure to continue using it. If split could take ownership // of the split values, then this wouldn't be needed - PipelineData::Value(Value::String { val, span }, ..) => { + PipelineData::Value(Value::String { val, .. }, ..) => { let mut lines = LINE_BREAK_REGEX .split(&val) .map(|s| s.to_string()) @@ -76,7 +76,8 @@ impl Command for Lines { let iter = stream .into_iter() .filter_map(move |value| { - if let Value::String { val, span } = value { + let span = value.span(); + if let Value::String { val, .. } = value { let mut lines = LINE_BREAK_REGEX .split(&val) .filter_map(|s| { @@ -96,11 +97,7 @@ impl Command for Lines { } } - Some( - lines - .into_iter() - .map(move |x| Value::String { val: x, span }), - ) + Some(lines.into_iter().map(move |x| Value::string(x, span))) } else { None } @@ -129,10 +126,7 @@ impl Command for Lines { .enumerate() .map(move |(_idx, x)| match x { Ok(x) => x, - Err(err) => Value::Error { - error: Box::new(err), - span: head, - }, + Err(err) => Value::error(err, head), }) .into_pipeline_data(ctrlc)), } @@ -142,10 +136,10 @@ impl Command for Lines { vec![Example { description: "Split multi-line string into lines", example: r#"$"two\nlines" | lines"#, - result: Some(Value::List { - vals: vec![Value::test_string("two"), Value::test_string("lines")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("two"), Value::test_string("lines")], + Span::test_data(), + )), }] } } @@ -175,10 +169,7 @@ impl Iterator for RawStreamLinesAdapter { continue; } - return Some(Ok(Value::String { - val: s, - span: self.span, - })); + return Some(Ok(Value::string(s, self.span))); } else { // inner is complete, feed out remaining state if self.inner_complete { @@ -198,9 +189,10 @@ impl Iterator for RawStreamLinesAdapter { if let Some(result) = self.inner.next() { match result { Ok(v) => { + let span = v.span(); match v { // TODO: Value::Binary support required? - Value::String { val, span } => { + Value::String { val, .. } => { self.span = span; let mut lines = LINE_BREAK_REGEX diff --git a/crates/nu-command/src/filters/merge.rs b/crates/nu-command/src/filters/merge.rs index b5e4df20b..f13f3024b 100644 --- a/crates/nu-command/src/filters/merge.rs +++ b/crates/nu-command/src/filters/merge.rs @@ -46,8 +46,8 @@ repeating this process with row 1, and so on."# Example { example: "[a b c] | wrap name | merge ( [1 2 3] | wrap index )", description: "Add an 'index' column to the input table", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["name".to_string(), "index".to_string()], vals: vec![Value::test_string("a"), Value::test_int(1)], @@ -61,8 +61,8 @@ repeating this process with row 1, and so on."# vals: vec![Value::test_string("c"), Value::test_int(3)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "{a: 1, b: 2} | merge {c: 3}", @@ -75,13 +75,13 @@ repeating this process with row 1, and so on."# Example { example: "[{columnA: A0 columnB: B0}] | merge [{columnA: 'A0*'}]", description: "Merge two tables, overwriting overlapping columns", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["columnA".to_string(), "columnB".to_string()], vals: vec![Value::test_string("A0*"), Value::test_string("B0")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -113,16 +113,10 @@ repeating this process with row 1, and so on."# .map(move |inp| match (inp.as_record(), table_iter.next()) { (Ok(inp), Some(to_merge)) => match to_merge.as_record() { Ok(to_merge) => Value::record(do_merge(inp, to_merge), call.head), - Err(error) => Value::Error { - error: Box::new(error), - span: call.head, - }, + Err(error) => Value::error(error, call.head), }, (_, None) => inp, - (Err(error), _) => Value::Error { - error: Box::new(error), - span: call.head, - }, + (Err(error), _) => Value::error(error, call.head), }); if let Some(md) = metadata { diff --git a/crates/nu-command/src/filters/move_.rs b/crates/nu-command/src/filters/move_.rs index d8aed5cfc..a521f0c18 100644 --- a/crates/nu-command/src/filters/move_.rs +++ b/crates/nu-command/src/filters/move_.rs @@ -52,8 +52,8 @@ impl Command for Move { example: "[[name value index]; [foo a 1] [bar b 2] [baz c 3]] | move index --before name", description: "Move a column before the first column", result: - Some(Value::List { - vals: vec![ + Some(Value::list ( + vec![ Value::test_record(Record { cols: vec!["index".to_string(), "name".to_string(), "value".to_string()], vals: vec![Value::test_int(1), Value::test_string("foo"), Value::test_string("a")], @@ -67,15 +67,15 @@ impl Command for Move { vals: vec![Value::test_int(3), Value::test_string("baz"), Value::test_string("c")], }), ], - span: Span::test_data(), - }) + Span::test_data(), + )) }, Example { example: "[[name value index]; [foo a 1] [bar b 2] [baz c 3]] | move value name --after index", description: "Move multiple columns after the last column and reorder them", result: - Some(Value::List { - vals: vec![ + Some(Value::list ( + vec![ Value::test_record(Record { cols: vec!["index".to_string(), "value".to_string(), "name".to_string()], vals: vec![Value::test_int(1), Value::test_string("a"), Value::test_string("foo")], @@ -89,8 +89,8 @@ impl Command for Move { vals: vec![Value::test_int(3), Value::test_string("c"), Value::test_string("baz")], }), ], - span: Span::test_data(), - }) + Span::test_data(), + )) }, Example { example: "{ name: foo, value: a, index: 1 } | move name --before index", @@ -153,16 +153,10 @@ impl Command for Move { Ok(record) => { match move_record_columns(record, &columns, &before_or_after, call.head) { Ok(val) => val, - Err(error) => Value::Error { - error: Box::new(error), - span: call.head, - }, + Err(error) => Value::error(error, call.head), } } - Err(error) => Value::Error { - error: Box::new(error), - span: call.head, - }, + Err(error) => Value::error(error, call.head), }); if let Some(md) = metadata { diff --git a/crates/nu-command/src/filters/par_each.rs b/crates/nu-command/src/filters/par_each.rs index 4f745f383..b0573d012 100644 --- a/crates/nu-command/src/filters/par_each.rs +++ b/crates/nu-command/src/filters/par_each.rs @@ -57,31 +57,31 @@ impl Command for ParEach { Example { example: r#"[foo bar baz] | par-each {|e| $e + '!' } | sort"#, description: "Output can still be sorted afterward", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("bar!"), Value::test_string("baz!"), Value::test_string("foo!"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: r#"1..3 | enumerate | par-each {|p| update item ($p.item * 2)} | sort-by item | get item"#, description: "Enumerate and sort-by can be used to reconstruct the original order", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(4), Value::test_int(6)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(4), Value::test_int(6)], + Span::test_data(), + )), }, Example { example: r#"[1 2 3] | enumerate | par-each { |e| if $e.item == 2 { $"found 2 at ($e.index)!"} }"#, description: "Iterate over each element, producing a list showing indexes of any 2s", - result: Some(Value::List { - vals: vec![Value::test_string("found 2 at 1!")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("found 2 at 1!")], + Span::test_data(), + )), }, ] } @@ -154,12 +154,10 @@ impl Command for ParEach { ) { Ok(v) => v.into_value(span), - Err(error) => Value::Error { - error: Box::new(chain_error_with_input( - error, x_is_error, val_span, - )), - span: val_span, - }, + Err(error) => Value::error( + chain_error_with_input(error, x_is_error, val_span), + val_span, + ), } }) .collect::>() @@ -192,12 +190,10 @@ impl Command for ParEach { redirect_stderr, ) { Ok(v) => v.into_value(span), - Err(error) => Value::Error { - error: Box::new(chain_error_with_input( - error, x_is_error, val_span, - )), - span: val_span, - }, + Err(error) => Value::error( + chain_error_with_input(error, x_is_error, val_span), + val_span, + ), } }) .collect::>() @@ -230,12 +226,10 @@ impl Command for ParEach { redirect_stderr, ) { Ok(v) => v.into_value(span), - Err(error) => Value::Error { - error: Box::new(chain_error_with_input( - error, x_is_error, val_span, - )), - span: val_span, - }, + Err(error) => Value::error( + chain_error_with_input(error, x_is_error, val_span), + val_span, + ), } }) .collect::>() @@ -252,12 +246,7 @@ impl Command for ParEach { .map(move |x| { let x = match x { Ok(x) => x, - Err(err) => { - return Value::Error { - error: Box::new(err), - span, - } - } + Err(err) => return Value::error(err, span), }; let block = engine_state.get_block(block_id); @@ -279,10 +268,7 @@ impl Command for ParEach { redirect_stderr, ) { Ok(v) => v.into_value(span), - Err(error) => Value::Error { - error: Box::new(error), - span, - }, + Err(error) => Value::error(error, span), } }) .collect::>() diff --git a/crates/nu-command/src/filters/prepend.rs b/crates/nu-command/src/filters/prepend.rs index b916d8025..937fe4505 100644 --- a/crates/nu-command/src/filters/prepend.rs +++ b/crates/nu-command/src/filters/prepend.rs @@ -45,57 +45,57 @@ only unwrap the outer list, and leave the variable's contents untouched."# Example { example: "0 | prepend [1 2 3]", description: "prepend a list to an item", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(0), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: r#""a" | prepend ["b"] "#, description: "Prepend a list of strings to a string", - result: Some(Value::List { - vals: vec![Value::test_string("b"), Value::test_string("a")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("b"), Value::test_string("a")], + Span::test_data(), + )), }, Example { example: "[1,2,3,4] | prepend 0", description: "Prepend one integer item", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(4), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[2,3,4] | prepend [0,1]", description: "Prepend two integer items", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(4), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[2,nu,4,shell] | prepend [0,1,rocks]", description: "Prepend integers and strings", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(0), Value::test_int(1), Value::test_string("rocks"), @@ -104,8 +104,8 @@ only unwrap the outer list, and leave the variable's contents untouched."# Value::test_int(4), Value::test_string("shell"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -132,8 +132,7 @@ only unwrap the outer list, and leave the variable's contents untouched."# fn process_value(val: Value) -> Vec { match val { Value::List { - vals: input_vals, - span: _, + vals: input_vals, .. } => { let mut output = vec![]; for input_val in input_vals { diff --git a/crates/nu-command/src/filters/range.rs b/crates/nu-command/src/filters/range.rs index 431ceca31..1fc20e9dd 100644 --- a/crates/nu-command/src/filters/range.rs +++ b/crates/nu-command/src/filters/range.rs @@ -38,26 +38,26 @@ impl Command for Range { Example { example: "[0,1,2,3,4,5] | range 4..5", description: "Get the last 2 items", - result: Some(Value::List { - vals: vec![Value::test_int(4), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(4), Value::test_int(5)], + Span::test_data(), + )), }, Example { example: "[0,1,2,3,4,5] | range (-2)..", description: "Get the last 2 items", - result: Some(Value::List { - vals: vec![Value::test_int(4), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(4), Value::test_int(5)], + Span::test_data(), + )), }, Example { example: "[0,1,2,3,4,5] | range (-3)..-2", description: "Get the next to last 2 items", - result: Some(Value::List { - vals: vec![Value::test_int(3), Value::test_int(4)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(3), Value::test_int(4)], + Span::test_data(), + )), }, ] } @@ -99,10 +99,7 @@ impl Command for Range { }; if from > to { - Ok(PipelineData::Value( - Value::Nothing { span: call.head }, - None, - )) + Ok(PipelineData::Value(Value::nothing(call.head), None)) } else { let iter = v.into_iter().skip(from).take(to - from + 1); Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) @@ -112,10 +109,7 @@ impl Command for Range { let to = rows_to as usize; if from > to { - Ok(PipelineData::Value( - Value::Nothing { span: call.head }, - None, - )) + Ok(PipelineData::Value(Value::nothing(call.head), None)) } else { let iter = input.into_iter().skip(from).take(to - from + 1); Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) diff --git a/crates/nu-command/src/filters/reject.rs b/crates/nu-command/src/filters/reject.rs index a86bf9144..e6a6adffa 100644 --- a/crates/nu-command/src/filters/reject.rs +++ b/crates/nu-command/src/filters/reject.rs @@ -62,13 +62,13 @@ impl Command for Reject { Example { description: "Reject a column in a table", example: "[[a, b]; [1, 2]] | reject a", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["b".to_string()], vals: vec![Value::test_int(2)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Reject the specified field in a record", diff --git a/crates/nu-command/src/filters/rename.rs b/crates/nu-command/src/filters/rename.rs index 69c883651..471e730c7 100644 --- a/crates/nu-command/src/filters/rename.rs +++ b/crates/nu-command/src/filters/rename.rs @@ -55,35 +55,35 @@ impl Command for Rename { Example { description: "Rename a column", example: "[[a, b]; [1, 2]] | rename my_column", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["my_column".to_string(), "b".to_string()], vals: vec![Value::test_int(1), Value::test_int(2)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rename many columns", example: "[[a, b, c]; [1, 2, 3]] | rename eggs ham bacon", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["eggs".to_string(), "ham".to_string(), "bacon".to_string()], vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rename a specific column", example: "[[a, b, c]; [1, 2, 3]] | rename -c [a ham]", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ham".to_string(), "b".to_string(), "c".to_string()], vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Rename the fields of a record", @@ -113,19 +113,23 @@ fn rename( ) -> Result { let specified_column: Option> = call.get_flag(engine_state, stack, "column")?; // get the span for the column's name to be changed and for the given list - let (specified_col_span, list_span) = if let Some(Value::List { - vals: columns, - span: column_span, - }) = call.get_flag(engine_state, stack, "column")? - { - if columns.is_empty() { - return Err(ShellError::TypeMismatch { err_message: "The column list cannot be empty and must contain only two values: the column's name and its replacement value" + let column_flag: Option = call.get_flag(engine_state, stack, "column")?; + let (specified_col_span, list_span) = match column_flag { + Some(column_flag) => { + let column_span = column_flag.span(); + match column_flag { + Value::List { vals: columns, .. } => { + if columns.is_empty() { + return Err(ShellError::TypeMismatch { err_message: "The column list cannot be empty and must contain only two values: the column's name and its replacement value" .to_string(), span: column_span }); - } else { - (Some(columns[0].span()), column_span) + } else { + (Some(columns[0].span()), column_span) + } + } + _ => (None, call.head), + } } - } else { - (None, call.head) + None => (None, call.head), }; if let Some(ref cols) = specified_column { @@ -155,100 +159,92 @@ fn rename( let head_span = call.head; input .map( - move |item| match item { - Value::Record { - val: mut record, - span, - } => { - if let Some((engine_state, block, mut stack, env_vars, env_hidden)) = - block_info.clone() - { - for c in &mut record.cols { - stack.with_env(&env_vars, &env_hidden); + move |item| { + let span = item.span(); + match item { + Value::Record { + val: mut record, .. + } => { + if let Some((engine_state, block, mut stack, env_vars, env_hidden)) = + block_info.clone() + { + for c in &mut record.cols { + stack.with_env(&env_vars, &env_hidden); - if let Some(var) = block.signature.get_positional(0) { - if let Some(var_id) = &var.var_id { - stack.add_var(*var_id, Value::string(c.clone(), span)) - } - } - let eval_result = eval_block_with_early_return( - &engine_state, - &mut stack, - &block, - Value::string(c.clone(), span).into_pipeline_data(), - redirect_stdout, - redirect_stderr, - ); - match eval_result { - Err(e) => { - return Value::Error { - error: Box::new(e), - span, + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + stack.add_var(*var_id, Value::string(c.clone(), span)) } } - Ok(res) => match res.collect_string_strict(span) { - Err(e) => { - return Value::Error { - error: Box::new(e), + let eval_result = eval_block_with_early_return( + &engine_state, + &mut stack, + &block, + Value::string(c.clone(), span).into_pipeline_data(), + redirect_stdout, + redirect_stderr, + ); + match eval_result { + Err(e) => return Value::error(e, span), + Ok(res) => match res.collect_string_strict(span) { + Err(e) => return Value::error(e, span), + Ok(new_c) => *c = new_c.0, + }, + } + } + } else { + match &specified_column { + Some(c) => { + // check if the specified column to be renamed exists + if !record.cols.contains(&c[0]) { + return Value::error( + ShellError::UnsupportedInput( + format!( + "The column '{}' does not exist in the input", + &c[0] + ), + "value originated from here".into(), + // Arrow 1 points at the specified column name, + specified_col_span.unwrap_or(head_span), + // Arrow 2 points at the input value. + span, + ), span, + ); + } + for (idx, val) in record.cols.iter_mut().enumerate() { + if *val == c[0] { + record.cols[idx] = c[1].to_string(); + break; } } - Ok(new_c) => *c = new_c.0, - }, - } - } - } else { - match &specified_column { - Some(c) => { - // check if the specified column to be renamed exists - if !record.cols.contains(&c[0]) { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( - format!( - "The column '{}' does not exist in the input", - &c[0] - ), - "value originated from here".into(), - // Arrow 1 points at the specified column name, - specified_col_span.unwrap_or(head_span), - // Arrow 2 points at the input value. - span, - )), - span, - }; } - for (idx, val) in record.cols.iter_mut().enumerate() { - if *val == c[0] { - record.cols[idx] = c[1].to_string(); - break; + None => { + for (idx, val) in columns.iter().enumerate() { + if idx >= record.len() { + // skip extra new columns names if we already reached the final column + break; + } + record.cols[idx] = val.clone(); } } } - None => { - for (idx, val) in columns.iter().enumerate() { - if idx >= record.len() { - // skip extra new columns names if we already reached the final column - break; - } - record.cols[idx] = val.clone(); - } - } } - } - Value::record(record, span) + Value::record(record, span) + } + // Propagate errors by explicitly matching them before the final case. + Value::Error { .. } => item.clone(), + other => Value::error( + ShellError::OnlySupportsThisInputType { + exp_input_type: "record".into(), + wrong_type: other.get_type().to_string(), + dst_span: head_span, + src_span: other.span(), + }, + head_span, + ), } - // Propagate errors by explicitly matching them before the final case. - Value::Error { .. } => item.clone(), - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { - exp_input_type: "record".into(), - wrong_type: other.get_type().to_string(), - dst_span: head_span, - src_span: other.span(), - }), - span: head_span, - }, }, engine_state.ctrlc.clone(), ) diff --git a/crates/nu-command/src/filters/reverse.rs b/crates/nu-command/src/filters/reverse.rs index 6a75ec569..a97eaf863 100644 --- a/crates/nu-command/src/filters/reverse.rs +++ b/crates/nu-command/src/filters/reverse.rs @@ -38,21 +38,21 @@ impl Command for Reverse { Example { example: "[0,1,2,3] | reverse", description: "Reverse a list", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(3), Value::test_int(2), Value::test_int(1), Value::test_int(0), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[{a: 1} {a: 2}] | reverse", description: "Reverse a table", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(2)], @@ -62,8 +62,8 @@ impl Command for Reverse { vals: vec![Value::test_int(1)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index 80d07ce79..9a62565de 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -151,13 +151,13 @@ produce a table, a list will produce a list, and a record will produce a record. Example { description: "Select a column in a table", example: "[{a: a b: b}] | select a", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_string("a")] })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Select a field in a record", @@ -250,44 +250,65 @@ fn select( }; match input { - PipelineData::Value( - Value::List { - vals: input_vals, - span, - }, - metadata, - .., - ) => { - let mut output = vec![]; - let mut columns_with_value = Vec::new(); - for input_val in input_vals { - if !columns.is_empty() { - let mut record = Record::new(); - for path in &columns { - //FIXME: improve implementation to not clone - match input_val.clone().follow_cell_path(&path.members, false) { - Ok(fetcher) => { - record.push(path.into_string().replace('.', "_"), fetcher); - if !columns_with_value.contains(&path) { - columns_with_value.push(path); + PipelineData::Value(v, metadata, ..) => { + let span = v.span(); + match v { + Value::List { + vals: input_vals, .. + } => { + let mut output = vec![]; + let mut columns_with_value = Vec::new(); + for input_val in input_vals { + if !columns.is_empty() { + let mut record = Record::new(); + for path in &columns { + //FIXME: improve implementation to not clone + match input_val.clone().follow_cell_path(&path.members, false) { + Ok(fetcher) => { + record.push(path.into_string().replace('.', "_"), fetcher); + if !columns_with_value.contains(&path) { + columns_with_value.push(path); + } + } + Err(e) => { + return Err(e); + } } } - Err(e) => { - return Err(e); - } + + output.push(Value::record(record, span)) + } else { + output.push(input_val) } } - output.push(Value::record(record, span)) - } else { - output.push(input_val) + Ok(output + .into_iter() + .into_pipeline_data(engine_state.ctrlc.clone()) + .set_metadata(metadata)) + } + _ => { + if !columns.is_empty() { + let mut record = Record::new(); + + for cell_path in columns { + // FIXME: remove clone + match v.clone().follow_cell_path(&cell_path.members, false) { + Ok(result) => { + record.push(cell_path.into_string().replace('.', "_"), result); + } + Err(e) => return Err(e), + } + } + + Ok(Value::record(record, call_span) + .into_pipeline_data() + .set_metadata(metadata)) + } else { + Ok(v.into_pipeline_data().set_metadata(metadata)) + } } } - - Ok(output - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone()) - .set_metadata(metadata)) } PipelineData::ListStream(stream, metadata, ..) => { let mut values = vec![]; @@ -314,27 +335,6 @@ fn select( .into_pipeline_data(engine_state.ctrlc.clone()) .set_metadata(metadata)) } - PipelineData::Value(v, metadata, ..) => { - if !columns.is_empty() { - let mut record = Record::new(); - - for cell_path in columns { - // FIXME: remove clone - match v.clone().follow_cell_path(&cell_path.members, false) { - Ok(result) => { - record.push(cell_path.into_string().replace('.', "_"), result); - } - Err(e) => return Err(e), - } - } - - Ok(Value::record(record, call_span) - .into_pipeline_data() - .set_metadata(metadata)) - } else { - Ok(v.into_pipeline_data().set_metadata(metadata)) - } - } _ => Ok(PipelineData::empty()), } } diff --git a/crates/nu-command/src/filters/skip/skip_.rs b/crates/nu-command/src/filters/skip/skip_.rs index f44d3d5a8..1ee192e73 100644 --- a/crates/nu-command/src/filters/skip/skip_.rs +++ b/crates/nu-command/src/filters/skip/skip_.rs @@ -46,25 +46,24 @@ impl Command for Skip { Example { description: "Skip the first value of a list", example: "[2 4 6 8] | skip 1", - result: Some(Value::List { - vals: vec![Value::test_int(4), Value::test_int(6), Value::test_int(8)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(4), Value::test_int(6), Value::test_int(8)], + Span::test_data(), + )), }, Example { description: "Skip two rows of a table", example: "[[editions]; [2015] [2018] [2021]] | skip 2", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["editions".to_owned()], vals: vec![Value::test_int(2021)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } - fn run( &self, engine_state: &EngineState, @@ -73,27 +72,33 @@ impl Command for Skip { input: PipelineData, ) -> Result { let n: Option = call.opt(engine_state, stack, 0)?; - let span = call.head; let metadata = input.metadata(); let n: usize = match n { - Some(Value::Int { val, span }) => { - val.try_into().map_err(|err| ShellError::TypeMismatch { - err_message: format!("Could not convert {val} to unsigned integer: {err}"), - span, - })? - } - Some(_) => { - return Err(ShellError::TypeMismatch { - err_message: "expected integer".into(), - span, - }) + Some(v) => { + let span = v.span(); + match v { + Value::Int { val, .. } => { + val.try_into().map_err(|err| ShellError::TypeMismatch { + err_message: format!( + "Could not convert {val} to unsigned integer: {err}" + ), + span, + })? + } + _ => { + return Err(ShellError::TypeMismatch { + err_message: "expected integer".into(), + span, + }) + } + } } None => 1, }; let ctrlc = engine_state.ctrlc.clone(); - + let input_span = input.span().unwrap_or(call.head); match input { PipelineData::ExternalStream { stdout: Some(stream), @@ -130,17 +135,14 @@ impl Command for Skip { } } - Ok(Value::Binary { - val: output, - span: bytes_span, - } - .into_pipeline_data() - .set_metadata(metadata)) + Ok(Value::binary(output, bytes_span) + .into_pipeline_data() + .set_metadata(metadata)) } - PipelineData::Value(Value::Binary { val, span }, metadata) => { + PipelineData::Value(Value::Binary { val, .. }, metadata) => { let bytes = val.into_iter().skip(n).collect::>(); - Ok(Value::Binary { val: bytes, span } + Ok(Value::binary(bytes, input_span) .into_pipeline_data() .set_metadata(metadata)) } diff --git a/crates/nu-command/src/filters/skip/skip_until.rs b/crates/nu-command/src/filters/skip/skip_until.rs index 1662809bb..609c28614 100644 --- a/crates/nu-command/src/filters/skip/skip_until.rs +++ b/crates/nu-command/src/filters/skip/skip_until.rs @@ -44,24 +44,24 @@ impl Command for SkipUntil { Example { description: "Skip until the element is positive", example: "[-2 0 2 -1] | skip until {|x| $x > 0 }", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(-1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(-1)], + Span::test_data(), + )), }, Example { description: "Skip until the element is positive using stored condition", example: "let cond = {|x| $x > 0 }; [-2 0 2 -1] | skip until $cond", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(-1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(-1)], + Span::test_data(), + )), }, Example { description: "Skip until the field value is positive", example: "[{a: -2} {a: 0} {a: 2} {a: -1}] | skip until {|x| $x.a > 0 }", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(2)], @@ -71,8 +71,8 @@ impl Command for SkipUntil { vals: vec![Value::test_int(-1)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/skip/skip_while.rs b/crates/nu-command/src/filters/skip/skip_while.rs index e5f78091d..266b62df0 100644 --- a/crates/nu-command/src/filters/skip/skip_while.rs +++ b/crates/nu-command/src/filters/skip/skip_while.rs @@ -44,24 +44,24 @@ impl Command for SkipWhile { Example { description: "Skip while the element is negative", example: "[-2 0 2 -1] | skip while {|x| $x < 0 }", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(2), Value::test_int(-1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(2), Value::test_int(-1)], + Span::test_data(), + )), }, Example { description: "Skip while the element is negative using stored condition", example: "let cond = {|x| $x < 0 }; [-2 0 2 -1] | skip while $cond", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(2), Value::test_int(-1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(2), Value::test_int(-1)], + Span::test_data(), + )), }, Example { description: "Skip while the field value is negative", example: "[{a: -2} {a: 0} {a: 2} {a: -1}] | skip while {|x| $x.a < 0 }", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(0)], @@ -75,8 +75,8 @@ impl Command for SkipWhile { vals: vec![Value::test_int(-1)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/sort.rs b/crates/nu-command/src/filters/sort.rs index a8775f99e..7f219f229 100644 --- a/crates/nu-command/src/filters/sort.rs +++ b/crates/nu-command/src/filters/sort.rs @@ -49,66 +49,66 @@ impl Command for Sort { Example { example: "[2 0 1] | sort", description: "sort the list by increasing value", - result: Some(Value::List { - vals: vec![Value::test_int(0), Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(0), Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )), }, Example { example: "[2 0 1] | sort -r", description: "sort the list by decreasing value", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(1), Value::test_int(0)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(1), Value::test_int(0)], + Span::test_data(), + )), }, Example { example: "[betty amy sarah] | sort", description: "sort a list of strings", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("amy"), Value::test_string("betty"), Value::test_string("sarah"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[betty amy sarah] | sort -r", description: "sort a list of strings in reverse", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("sarah"), Value::test_string("betty"), Value::test_string("amy"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Sort strings (case-insensitive)", example: "[airplane Truck Car] | sort -i", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("airplane"), Value::test_string("Car"), Value::test_string("Truck"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Sort strings (reversed case-insensitive)", example: "[airplane Truck Car] | sort -i -r", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("Truck"), Value::test_string("Car"), Value::test_string("airplane"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Sort record by key (case-insensitive)", @@ -141,9 +141,10 @@ impl Command for Sort { let natural = call.has_flag("natural"); let metadata = &input.metadata(); + let span = input.span().unwrap_or(call.head); match input { // Records have two sorting methods, toggled by presence or absence of -v - PipelineData::Value(Value::Record { val, span }, ..) => { + PipelineData::Value(Value::Record { val, .. }, ..) => { let sort_by_value = call.has_flag("values"); let record = sort_record(val, span, sort_by_value, reverse, insensitive, natural); Ok(record.into_pipeline_data()) @@ -257,20 +258,20 @@ pub fn sort( } _ => { vec.sort_by(|a, b| { + let span_a = a.span(); + let span_b = b.span(); if insensitive { let lowercase_left = match a { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span: *span, - }, + Value::String { val, .. } => { + Value::string(val.to_ascii_lowercase(), span_a) + } _ => a.clone(), }; let lowercase_right = match b { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span: *span, - }, + Value::String { val, .. } => { + Value::string(val.to_ascii_lowercase(), span_b) + } _ => b.clone(), }; @@ -311,30 +312,26 @@ pub fn process( let left_res = match left_value { Some(left_res) => left_res, - None => Value::Nothing { span }, + None => Value::nothing(span), }; let right_value = right.get_data_by_key(column); let right_res = match right_value { Some(right_res) => right_res, - None => Value::Nothing { span }, + None => Value::nothing(span), }; let result = if insensitive { + let span_left = left_res.span(); + let span_right = right_res.span(); let lowercase_left = match left_res { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span, - }, + Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), span_left), _ => left_res, }; let lowercase_right = match right_res { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span, - }, + Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), span_right), _ => right_res, }; if natural { diff --git a/crates/nu-command/src/filters/sort_by.rs b/crates/nu-command/src/filters/sort_by.rs index a53375f72..c33c17138 100644 --- a/crates/nu-command/src/filters/sort_by.rs +++ b/crates/nu-command/src/filters/sort_by.rs @@ -58,8 +58,8 @@ impl Command for SortBy { Example { description: "Sort a table by a column (reversed order)", example: "[[fruit count]; [apple 9] [pear 3] [orange 7]] | sort-by fruit -r", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("pear"), Value::test_int(3)], @@ -73,8 +73,8 @@ impl Command for SortBy { vals: vec![Value::test_string("apple"), Value::test_int(9)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/split_by.rs b/crates/nu-command/src/filters/split_by.rs index be2324a9a..7b239f097 100644 --- a/crates/nu-command/src/filters/split_by.rs +++ b/crates/nu-command/src/filters/split_by.rs @@ -53,8 +53,8 @@ impl Command for SplitBy { vals: vec![ Value::test_record(Record { cols: vec!["2019".to_string()], - vals: vec![Value::List { - vals: vec![Value::test_record(Record { + vals: vec![Value::list( + vec![Value::test_record(Record { cols: vec![ "name".to_string(), "lang".to_string(), @@ -66,14 +66,14 @@ impl Command for SplitBy { Value::test_string("2019"), ], })], - span: Span::test_data(), - }], + Span::test_data(), + )], }), Value::test_record(Record { cols: vec!["2019".to_string(), "2021".to_string()], vals: vec![ - Value::List { - vals: vec![Value::test_record(Record { + Value::list( + vec![Value::test_record(Record { cols: vec![ "name".to_string(), "lang".to_string(), @@ -85,10 +85,10 @@ impl Command for SplitBy { Value::test_string("2019"), ], })], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_record(Record { + Span::test_data(), + ), + Value::list( + vec![Value::test_record(Record { cols: vec![ "name".to_string(), "lang".to_string(), @@ -100,8 +100,8 @@ impl Command for SplitBy { Value::test_string("2021"), ], })], - span: Span::test_data(), - }, + Span::test_data(), + ), ], }), ], @@ -215,20 +215,34 @@ pub fn data_split( let mut splits = indexmap::IndexMap::new(); match value { - PipelineData::Value(Value::Record { val: grouped, span }, _) => { - for (idx, list) in grouped.vals.iter().enumerate() { - match data_group(list, splitter, span) { - Ok(grouped_vals) => { - if let Value::Record { val: sub, .. } = grouped_vals { - for (inner_idx, subset) in sub.vals.iter().enumerate() { - let s: &mut IndexMap = - splits.entry(sub.cols[inner_idx].clone()).or_default(); + PipelineData::Value(v, _) => { + let span = v.span(); + match v { + Value::Record { val: grouped, .. } => { + for (idx, list) in grouped.vals.iter().enumerate() { + match data_group(list, splitter, span) { + Ok(grouped_vals) => { + if let Value::Record { val: sub, .. } = grouped_vals { + for (inner_idx, subset) in sub.vals.iter().enumerate() { + let s: &mut IndexMap = + splits.entry(sub.cols[inner_idx].clone()).or_default(); - s.insert(grouped.cols[idx].clone(), subset.clone()); + s.insert(grouped.cols[idx].clone(), subset.clone()); + } + } } + Err(reason) => return Err(reason), } } - Err(reason) => return Err(reason), + } + _ => { + return Err(ShellError::GenericError( + "unsupported input".into(), + "requires a table with one row for splitting".into(), + Some(span), + None, + Vec::new(), + )) } } } diff --git a/crates/nu-command/src/filters/take/take_.rs b/crates/nu-command/src/filters/take/take_.rs index 10d13a475..846dc21cf 100644 --- a/crates/nu-command/src/filters/take/take_.rs +++ b/crates/nu-command/src/filters/take/take_.rs @@ -54,33 +54,33 @@ impl Command for Take { let metadata = input.metadata(); match input { - PipelineData::Value(val, _) => match val { - Value::List { vals, .. } => Ok(vals - .into_iter() - .take(rows_desired) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)), - Value::Binary { val, span } => { - let slice: Vec = val.into_iter().take(rows_desired).collect(); - Ok(PipelineData::Value( - Value::Binary { val: slice, span }, - metadata, - )) + PipelineData::Value(val, _) => { + let span = val.span(); + match val { + Value::List { vals, .. } => Ok(vals + .into_iter() + .take(rows_desired) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)), + Value::Binary { val, .. } => { + let slice: Vec = val.into_iter().take(rows_desired).collect(); + Ok(PipelineData::Value(Value::binary(slice, span), metadata)) + } + Value::Range { val, .. } => Ok(val + .into_range_iter(ctrlc.clone())? + .take(rows_desired) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)), + // Propagate errors by explicitly matching them before the final case. + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "list, binary or range".into(), + wrong_type: other.get_type().to_string(), + dst_span: call.head, + src_span: other.span(), + }), } - Value::Range { val, .. } => Ok(val - .into_range_iter(ctrlc.clone())? - .take(rows_desired) - .into_pipeline_data(ctrlc) - .set_metadata(metadata)), - // Propagate errors by explicitly matching them before the final case. - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "list, binary or range".into(), - wrong_type: other.get_type().to_string(), - dst_span: call.head, - src_span: other.span(), - }), - }, + } PipelineData::ListStream(ls, metadata) => Ok(ls .take(rows_desired) .into_pipeline_data(ctrlc) @@ -107,24 +107,21 @@ impl Command for Take { Example { description: "Return the first item of a list/table", example: "[1 2 3] | take 1", - result: Some(Value::List { - vals: vec![Value::test_int(1)], - span: Span::test_data(), - }), + result: Some(Value::list(vec![Value::test_int(1)], Span::test_data())), }, Example { description: "Return the first 2 items of a list/table", example: "[1 2 3] | take 2", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )), }, Example { description: "Return the first two rows of a table", example: "[[editions]; [2015] [2018] [2021]] | take 2", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["editions".to_string()], vals: vec![Value::test_int(2015)], @@ -134,24 +131,21 @@ impl Command for Take { vals: vec![Value::test_int(2018)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Return the first 2 bytes of a binary value", example: "0x[01 23 45] | take 2", - result: Some(Value::Binary { - val: vec![0x01, 0x23], - span: Span::test_data(), - }), + result: Some(Value::binary(vec![0x01, 0x23], Span::test_data())), }, Example { description: "Return the first 3 elements of a range", example: "1..10 | take 3", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/take/take_until.rs b/crates/nu-command/src/filters/take/take_until.rs index cf3be0a6d..ae1887331 100644 --- a/crates/nu-command/src/filters/take/take_until.rs +++ b/crates/nu-command/src/filters/take/take_until.rs @@ -40,24 +40,24 @@ impl Command for TakeUntil { Example { description: "Take until the element is positive", example: "[-1 -2 9 1] | take until {|x| $x > 0 }", - result: Some(Value::List { - vals: vec![Value::test_int(-1), Value::test_int(-2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(-1), Value::test_int(-2)], + Span::test_data(), + )), }, Example { description: "Take until the element is positive using stored condition", example: "let cond = {|x| $x > 0 }; [-1 -2 9 1] | take until $cond", - result: Some(Value::List { - vals: vec![Value::test_int(-1), Value::test_int(-2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(-1), Value::test_int(-2)], + Span::test_data(), + )), }, Example { description: "Take until the field value is positive", example: "[{a: -1} {a: -2} {a: 9} {a: 1}] | take until {|x| $x.a > 0 }", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(-1)], @@ -67,8 +67,8 @@ impl Command for TakeUntil { vals: vec![Value::test_int(-2)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/take/take_while.rs b/crates/nu-command/src/filters/take/take_while.rs index b33374f09..8db101124 100644 --- a/crates/nu-command/src/filters/take/take_while.rs +++ b/crates/nu-command/src/filters/take/take_while.rs @@ -40,24 +40,24 @@ impl Command for TakeWhile { Example { description: "Take while the element is negative", example: "[-1 -2 9 1] | take while {|x| $x < 0 }", - result: Some(Value::List { - vals: vec![Value::test_int(-1), Value::test_int(-2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(-1), Value::test_int(-2)], + Span::test_data(), + )), }, Example { description: "Take while the element is negative using stored condition", example: "let cond = {|x| $x < 0 }; [-1 -2 9 1] | take while $cond", - result: Some(Value::List { - vals: vec![Value::test_int(-1), Value::test_int(-2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(-1), Value::test_int(-2)], + Span::test_data(), + )), }, Example { description: "Take while the field value is negative", example: "[{a: -1} {a: -2} {a: 9} {a: 1}] | take while {|x| $x.a < 0 }", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(-1)], @@ -67,8 +67,8 @@ impl Command for TakeWhile { vals: vec![Value::test_int(-2)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/transpose.rs b/crates/nu-command/src/filters/transpose.rs index d90331d6e..479bc38c9 100644 --- a/crates/nu-command/src/filters/transpose.rs +++ b/crates/nu-command/src/filters/transpose.rs @@ -88,8 +88,8 @@ impl Command for Transpose { Example { description: "Transposes the table contents with default column names", example: "[[c1 c2]; [1 2]] | transpose", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["column0".to_string(), "column1".to_string()], vals: vec![Value::test_string("c1"), Value::test_int(1)], @@ -100,13 +100,13 @@ impl Command for Transpose { }), ], span, - }), + )), }, Example { description: "Transposes the table contents with specified column names", example: "[[c1 c2]; [1 2]] | transpose key val", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["key".to_string(), "val".to_string()], vals: vec![Value::test_string("c1"), Value::test_int(1)], @@ -117,14 +117,14 @@ impl Command for Transpose { }), ], span, - }), + )), }, Example { description: "Transposes the table without column names and specify a new column name", example: "[[c1 c2]; [1 2]] | transpose -i val", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["val".to_string()], vals: vec![Value::test_int(1)], @@ -135,7 +135,7 @@ impl Command for Transpose { }), ], span, - }), + )), }, Example { description: "Transfer back to record with -d flag", @@ -260,19 +260,14 @@ pub fn transpose( .iter() .position(|y| y == &headers[column_num]) .expect("value is contained."); + let current_span = record.vals[index].span(); let new_val = match &record.vals[index] { - Value::List { vals, span } => { + Value::List { vals, .. } => { let mut vals = vals.clone(); vals.push(x.clone()); - Value::List { - vals: vals.to_vec(), - span: *span, - } + Value::list(vals.to_vec(), current_span) } - v => Value::List { - vals: vec![v.clone(), x.clone()], - span: v.span(), - }, + v => Value::list(vec![v.clone(), x.clone()], v.span()), }; record.cols.remove(index); record.vals.remove(index); @@ -298,19 +293,14 @@ pub fn transpose( .iter() .position(|y| y == &headers[column_num]) .expect("value is contained."); + let current_span = record.vals[index].span(); let new_val = match &record.vals[index] { - Value::List { vals, span } => { + Value::List { vals, .. } => { let mut vals = vals.clone(); vals.push(Value::nothing(name)); - Value::List { - vals: vals.to_vec(), - span: *span, - } + Value::list(vals.to_vec(), current_span) } - v => Value::List { - vals: vec![v.clone(), Value::nothing(name)], - span: v.span(), - }, + v => Value::list(vec![v.clone(), Value::nothing(name)], v.span()), }; record.cols.remove(index); record.vals.remove(index); diff --git a/crates/nu-command/src/filters/uniq.rs b/crates/nu-command/src/filters/uniq.rs index ac37b9b7b..d0f525288 100644 --- a/crates/nu-command/src/filters/uniq.rs +++ b/crates/nu-command/src/filters/uniq.rs @@ -88,40 +88,40 @@ impl Command for Uniq { Example { description: "Return the distinct values of a list/table (remove duplicates so that each value occurs once only)", example: "[2 3 3 4] | uniq", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(4)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(3), Value::test_int(4)], + Span::test_data(), + )), }, Example { description: "Return the input values that occur more than once", example: "[1 2 2] | uniq -d", - result: Some(Value::List { - vals: vec![Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2)], + Span::test_data(), + )), }, Example { description: "Return the input values that occur once only", example: "[1 2 2] | uniq -u", - result: Some(Value::List { - vals: vec![Value::test_int(1)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1)], + Span::test_data(), + )), }, Example { description: "Ignore differences in case when comparing input values", example: "['hello' 'goodbye' 'Hello'] | uniq -i", - result: Some(Value::List { - vals: vec![Value::test_string("hello"), Value::test_string("goodbye")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("hello"), Value::test_string("goodbye")], + Span::test_data(), + )), }, Example { description: "Return a table containing the distinct input values together with their counts", example: "[1 2 2] | uniq -c", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["value".to_string(), "count".to_string()], vals: vec![Value::test_int(1), Value::test_int(1)], @@ -131,8 +131,8 @@ impl Command for Uniq { vals: vec![Value::test_int(2), Value::test_int(2)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -185,29 +185,27 @@ impl ValueCounter { } fn clone_to_lowercase(value: &Value) -> Value { + let span = value.span(); match value { - Value::String { val: s, span } => Value::String { - val: s.clone().to_lowercase(), - span: *span, - }, - Value::List { vals: vec, span } => Value::List { - vals: vec.iter().map(clone_to_lowercase).collect(), - span: *span, - }, - Value::Record { val: record, span } => Value::record( + Value::String { val: s, .. } => Value::string(s.clone().to_lowercase(), span), + Value::List { vals: vec, .. } => { + Value::list(vec.iter().map(clone_to_lowercase).collect(), span) + } + Value::Record { val: record, .. } => Value::record( Record { cols: record.cols.clone(), vals: record.vals.iter().map(clone_to_lowercase).collect(), }, - *span, + span, ), other => other.clone(), } } fn sort_attributes(val: Value) -> Value { + let span = val.span(); match val { - Value::Record { val, span } => { + Value::Record { val, .. } => { let sorted = val .into_iter() .sorted_by(|a, b| a.0.cmp(&b.0)) @@ -227,10 +225,9 @@ fn sort_attributes(val: Value) -> Value { span, ) } - Value::List { vals, span } => Value::List { - vals: vals.into_iter().map(sort_attributes).collect_vec(), - span, - }, + Value::List { vals, .. } => { + Value::list(vals.into_iter().map(sort_attributes).collect_vec(), span) + } other => other, } } @@ -321,12 +318,9 @@ pub fn uniq( uniq_values.into_iter().map(|v| v.val).collect() }; - Ok(Value::List { - vals: result, - span: head, - } - .into_pipeline_data() - .set_metadata(metadata)) + Ok(Value::list(result, head) + .into_pipeline_data() + .set_metadata(metadata)) } fn sort(iter: IntoIter) -> Vec { diff --git a/crates/nu-command/src/filters/uniq_by.rs b/crates/nu-command/src/filters/uniq_by.rs index ea86a1261..e5d6c36ad 100644 --- a/crates/nu-command/src/filters/uniq_by.rs +++ b/crates/nu-command/src/filters/uniq_by.rs @@ -92,8 +92,8 @@ impl Command for UniqBy { vec![Example { description: "Get rows from table filtered by column uniqueness ", example: "[[fruit count]; [apple 9] [apple 2] [pear 3] [orange 7]] | uniq-by fruit", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("apple"), Value::test_int(9)], @@ -107,35 +107,35 @@ impl Command for UniqBy { vals: vec![Value::test_string("orange"), Value::test_int(7)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } fn validate(vec: Vec, columns: &Vec, span: Span) -> Result<(), ShellError> { - if let Some(Value::Record { - val: record, - span: val_span, - }) = vec.first() - { - if columns.is_empty() { - // This uses the same format as the 'requires a column name' error in split_by.rs - return Err(ShellError::GenericError( - "expected name".into(), - "requires a column name to filter table data".into(), - Some(span), - None, - Vec::new(), - )); - } + let first = vec.first(); + if let Some(v) = first { + let val_span = v.span(); + if let Value::Record { val: record, .. } = &v { + if columns.is_empty() { + // This uses the same format as the 'requires a column name' error in split_by.rs + return Err(ShellError::GenericError( + "expected name".into(), + "requires a column name to filter table data".into(), + Some(span), + None, + Vec::new(), + )); + } - if let Some(nonexistent) = nonexistent_column(columns.clone(), record.cols.clone()) { - return Err(ShellError::CantFindColumn { - col_name: nonexistent, - span, - src_span: *val_span, - }); + if let Some(nonexistent) = nonexistent_column(columns.clone(), record.cols.clone()) { + return Err(ShellError::CantFindColumn { + col_name: nonexistent, + span, + src_span: val_span, + }); + } } } @@ -155,10 +155,7 @@ fn item_mapper_by_col(cols: Vec) -> impl Fn(crate::ItemMapperState) -> c Box::new(move |ms: crate::ItemMapperState| -> crate::ValueCounter { let item_column_values = get_data_by_columns(&columns, &ms.item); - let col_vals = Value::List { - vals: item_column_values, - span: Span::unknown(), - }; + let col_vals = Value::list(item_column_values, Span::unknown()); crate::ValueCounter::new_vals_to_compare(ms.item, ms.flag_ignore_case, col_vals, ms.index) }) diff --git a/crates/nu-command/src/filters/update.rs b/crates/nu-command/src/filters/update.rs index f54229022..459ae7db7 100644 --- a/crates/nu-command/src/filters/update.rs +++ b/crates/nu-command/src/filters/update.rs @@ -65,35 +65,35 @@ impl Command for Update { Example { description: "Use in closure form for more involved updating logic", example: "[[count fruit]; [1 'apple']] | enumerate | update item.count {|e| ($e.item.fruit | str length) + $e.index } | get item", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["count".into(), "fruit".into()], vals: vec![Value::test_int(5), Value::test_string("apple")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Alter each value in the 'authors' column to use a single string instead of a list", example: "[[project, authors]; ['nu', ['Andrés', 'JT', 'Yehuda']]] | update authors {|row| $row.authors | str join ','}", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["project".into(), "authors".into()], vals: vec![Value::test_string("nu"), Value::test_string("Andrés,JT,Yehuda")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "You can also use a simple command to update 'authors' to a single string", example: "[[project, authors]; ['nu', ['Andrés', 'JT', 'Yehuda']]] | update authors {|| str join ','}", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["project".into(), "authors".into()], vals: vec![Value::test_string("nu"), Value::test_string("Andrés,JT,Yehuda")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), } ] } @@ -140,12 +140,7 @@ fn update( let input_at_path = match input.clone().follow_cell_path(&cell_path.members, false) { - Err(e) => { - return Value::Error { - error: Box::new(e), - span, - } - } + Err(e) => return Value::error(e, span), Ok(v) => v, }; let output = eval_block( @@ -162,18 +157,12 @@ fn update( if let Err(e) = input.update_data_at_cell_path(&cell_path.members, pd.into_value(span)) { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } input } - Err(e) => Value::Error { - error: Box::new(e), - span, - }, + Err(e) => Value::error(e, span), } }, ctrlc, @@ -210,10 +199,7 @@ fn update( let replacement = replacement.clone(); if let Err(e) = input.update_data_at_cell_path(&cell_path.members, replacement) { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } input diff --git a/crates/nu-command/src/filters/upsert.rs b/crates/nu-command/src/filters/upsert.rs index 56f378869..d11400fb2 100644 --- a/crates/nu-command/src/filters/upsert.rs +++ b/crates/nu-command/src/filters/upsert.rs @@ -68,8 +68,8 @@ impl Command for Upsert { Example { description: "Update each row of a table", example: "[[name lang]; [Nushell ''] [Reedline '']] | upsert lang 'Rust'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["name".into(), "lang".into()], vals: vec![Value::test_string("Nushell"), Value::test_string("Rust")], @@ -79,8 +79,8 @@ impl Command for Upsert { vals: vec![Value::test_string("Reedline"), Value::test_string("Rust")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Insert a new entry into a single record", @@ -92,34 +92,34 @@ impl Command for Upsert { }, Example { description: "Use in closure form for more involved updating logic", example: "[[count fruit]; [1 'apple']] | enumerate | upsert item.count {|e| ($e.item.fruit | str length) + $e.index } | get item", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["count".into(), "fruit".into()], vals: vec![Value::test_int(5), Value::test_string("apple")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Upsert an int into a list, updating an existing value based on the index", example: "[1 2 3] | upsert 0 2", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(2), Value::test_int(3)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(2), Value::test_int(3)], + Span::test_data(), + )), }, Example { description: "Upsert an int into a list, inserting a new value based on the index", example: "[1 2 3] | upsert 3 4", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(1), Value::test_int(2), Value::test_int(3), Value::test_int(4), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -178,18 +178,12 @@ fn upsert( if let Err(e) = input.upsert_data_at_cell_path(&cell_path.members, pd.into_value(span)) { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } input } - Err(e) => Value::Error { - error: Box::new(e), - span, - }, + Err(e) => Value::error(e, span), } }, ctrlc, @@ -225,10 +219,7 @@ fn upsert( let replacement = replacement.clone(); if let Err(e) = input.upsert_data_at_cell_path(&cell_path.members, replacement) { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } input diff --git a/crates/nu-command/src/filters/utils.rs b/crates/nu-command/src/filters/utils.rs index 9e9b64cef..1415ab957 100644 --- a/crates/nu-command/src/filters/utils.rs +++ b/crates/nu-command/src/filters/utils.rs @@ -62,19 +62,11 @@ pub fn boolean_fold( } Ok(pipeline_data) => { if pipeline_data.into_value(span).is_true() == accumulator { - return Ok(Value::Bool { - val: accumulator, - span, - } - .into_pipeline_data()); + return Ok(Value::bool(accumulator, span).into_pipeline_data()); } } } } - Ok(Value::Bool { - val: !accumulator, - span, - } - .into_pipeline_data()) + Ok(Value::bool(!accumulator, span).into_pipeline_data()) } diff --git a/crates/nu-command/src/filters/values.rs b/crates/nu-command/src/filters/values.rs index d1cb0e0b2..023cf6c8e 100644 --- a/crates/nu-command/src/filters/values.rs +++ b/crates/nu-command/src/filters/values.rs @@ -36,16 +36,16 @@ impl Command for Values { Example { example: "{ mode:normal userid:31415 } | values", description: "Get the values from the record (produce a list)", - result: Some(Value::List { - vals: vec![Value::test_string("normal"), Value::test_int(31415)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("normal"), Value::test_int(31415)], + Span::test_data(), + )), }, Example { example: "{ f:250 g:191 c:128 d:1024 e:2000 a:16 b:32 } | values", description: "Values are ordered by the column order of the record", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(250), Value::test_int(191), Value::test_int(128), @@ -54,33 +54,33 @@ impl Command for Values { Value::test_int(16), Value::test_int(32), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "[[name meaning]; [ls list] [mv move] [cd 'change directory']] | values", description: "Get the values from the table (produce a list of lists)", - result: Some(Value::List { - vals: vec![ - Value::List { - vals: vec![ + result: Some(Value::list( + vec![ + Value::list( + vec![ Value::test_string("ls"), Value::test_string("mv"), Value::test_string("cd"), ], - span: Span::test_data(), - }, - Value::List { - vals: vec![ + Span::test_data(), + ), + Value::list( + vec![ Value::test_string("list"), Value::test_string("move"), Value::test_string("change directory"), ], - span: Span::test_data(), - }, + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -143,23 +143,37 @@ fn values( let metadata = input.metadata(); match input { PipelineData::Empty => Ok(PipelineData::Empty), - PipelineData::Value(Value::List { vals, span }, ..) => { - match get_values(&vals, head, span) { - Ok(cols) => Ok(cols - .into_iter() - .into_pipeline_data(ctrlc) - .set_metadata(metadata)), - Err(err) => Err(err), - } - } - PipelineData::Value(Value::CustomValue { val, span }, ..) => { - let input_as_base_value = val.to_base_value(span)?; - match get_values(&[input_as_base_value], head, span) { - Ok(cols) => Ok(cols - .into_iter() - .into_pipeline_data(ctrlc) - .set_metadata(metadata)), - Err(err) => Err(err), + PipelineData::Value(v, ..) => { + let span = v.span(); + match v { + Value::List { vals, .. } => match get_values(&vals, head, span) { + Ok(cols) => Ok(cols + .into_iter() + .into_pipeline_data(ctrlc) + .set_metadata(metadata)), + Err(err) => Err(err), + }, + Value::CustomValue { val, .. } => { + let input_as_base_value = val.to_base_value(span)?; + match get_values(&[input_as_base_value], head, span) { + Ok(cols) => Ok(cols + .into_iter() + .into_pipeline_data(ctrlc) + .set_metadata(metadata)), + Err(err) => Err(err), + } + } + Value::Record { val, .. } => { + Ok(val.vals.into_pipeline_data(ctrlc).set_metadata(metadata)) + } + // Propagate errors + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "record or table".into(), + wrong_type: other.get_type().to_string(), + dst_span: head, + src_span: other.span(), + }), } } PipelineData::ListStream(stream, ..) => { @@ -172,17 +186,6 @@ fn values( Err(err) => Err(err), } } - PipelineData::Value(Value::Record { val, .. }, ..) => { - Ok(val.vals.into_pipeline_data(ctrlc).set_metadata(metadata)) - } - // Propagate errors - PipelineData::Value(Value::Error { error, .. }, ..) => Err(*error), - PipelineData::Value(other, ..) => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "record or table".into(), - wrong_type: other.get_type().to_string(), - dst_span: head, - src_span: other.span(), - }), PipelineData::ExternalStream { .. } => Err(ShellError::OnlySupportsThisInputType { exp_input_type: "record or table".into(), wrong_type: "raw data".into(), diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index 59e09eff7..566504977 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -99,10 +99,7 @@ not supported."# None } } - Err(err) => Some(Value::Error { - error: Box::new(err), - span, - }), + Err(err) => Some(Value::error(err, span)), } }) .into_pipeline_data(ctrlc) @@ -114,21 +111,21 @@ not supported."# Example { description: "Filter rows of a table according to a condition", example: "[{a: 1} {a: 2}] | where a > 1", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(2)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Filter items of a list according to a condition", example: "[1 2] | where {|x| $x > 1}", - result: Some(Value::List { - vals: vec![Value::test_int(2)], - span: Span::test_data(), - }), + result: Some(Value::list ( + vec![Value::test_int(2)], + Span::test_data(), + )), }, Example { description: "List all files in the current directory with sizes greater than 2kb", diff --git a/crates/nu-command/src/filters/window.rs b/crates/nu-command/src/filters/window.rs index b92a22ce1..8ebddb625 100644 --- a/crates/nu-command/src/filters/window.rs +++ b/crates/nu-command/src/filters/window.rs @@ -41,70 +41,70 @@ impl Command for Window { fn examples(&self) -> Vec { let stream_test_1 = vec![ - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(2), Value::test_int(3)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(3), Value::test_int(4)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(2), Value::test_int(3)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(3), Value::test_int(4)], + Span::test_data(), + ), ]; let stream_test_2 = vec![ - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(4), Value::test_int(5)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(7), Value::test_int(8)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(4), Value::test_int(5)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(7), Value::test_int(8)], + Span::test_data(), + ), ]; let stream_test_3 = vec![ - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(4), Value::test_int(5)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(4), Value::test_int(5)], + Span::test_data(), + ), ]; vec![ Example { example: "[1 2 3 4] | window 2", description: "A sliding window of two elements", - result: Some(Value::List { - vals: stream_test_1, - span: Span::test_data(), - }), + result: Some(Value::list( + stream_test_1, + Span::test_data(), + )), }, Example { example: "[1, 2, 3, 4, 5, 6, 7, 8] | window 2 --stride 3", description: "A sliding window of two elements, with a stride of 3", - result: Some(Value::List { - vals: stream_test_2, - span: Span::test_data(), - }), + result: Some(Value::list( + stream_test_2, + Span::test_data(), + )), }, Example { example: "[1, 2, 3, 4, 5] | window 3 --stride 3 --remainder", description: "A sliding window of equal stride that includes remainder. Equivalent to chunking", - result: Some(Value::List { - vals: stream_test_3, - span: Span::test_data(), - }), + result: Some(Value::list( + stream_test_3, + Span::test_data(), + )), }, ] } @@ -224,10 +224,7 @@ impl Iterator for EachWindowIterator { let return_group = group.clone(); self.previous = Some(group); - Some(Value::List { - vals: return_group, - span: self.span, - }) + Some(Value::list(return_group, self.span)) } } diff --git a/crates/nu-command/src/filters/wrap.rs b/crates/nu-command/src/filters/wrap.rs index 721c4bc12..c2f23ebc3 100644 --- a/crates/nu-command/src/filters/wrap.rs +++ b/crates/nu-command/src/filters/wrap.rs @@ -67,8 +67,8 @@ impl Command for Wrap { Example { description: "Wrap a list into a table with a given column name", example: "[1 2 3] | wrap num", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["num".into()], vals: vec![Value::test_int(1)], @@ -82,14 +82,14 @@ impl Command for Wrap { vals: vec![Value::test_int(3)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Wrap a range into a table with a given column name", example: "1..3 | wrap num", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["num".into()], vals: vec![Value::test_int(1)], @@ -103,8 +103,8 @@ impl Command for Wrap { vals: vec![Value::test_int(3)], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } diff --git a/crates/nu-command/src/filters/zip.rs b/crates/nu-command/src/filters/zip.rs index 374f7cf9d..745451302 100644 --- a/crates/nu-command/src/filters/zip.rs +++ b/crates/nu-command/src/filters/zip.rs @@ -35,46 +35,46 @@ impl Command for Zip { } fn examples(&self) -> Vec { - let test_row_1 = Value::List { - vals: vec![Value::test_int(1), Value::test_int(4)], - span: Span::test_data(), - }; + let test_row_1 = Value::list( + vec![Value::test_int(1), Value::test_int(4)], + Span::test_data(), + ); - let test_row_2 = Value::List { - vals: vec![Value::test_int(2), Value::test_int(5)], - span: Span::test_data(), - }; + let test_row_2 = Value::list( + vec![Value::test_int(2), Value::test_int(5)], + Span::test_data(), + ); - let test_row_3 = Value::List { - vals: vec![Value::test_int(3), Value::test_int(6)], - span: Span::test_data(), - }; + let test_row_3 = Value::list( + vec![Value::test_int(3), Value::test_int(6)], + Span::test_data(), + ); vec![ Example { example: "[1 2] | zip [3 4]", description: "Zip two lists", - result: Some(Value::List { - vals: vec![ - Value::List { - vals: vec![Value::test_int(1), Value::test_int(3)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(2), Value::test_int(4)], - span: Span::test_data(), - }, + result: Some(Value::list( + vec![ + Value::list( + vec![Value::test_int(1), Value::test_int(3)], + Span::test_data(), + ), + Value::list( + vec![Value::test_int(2), Value::test_int(4)], + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: "1..3 | zip 4..6", description: "Zip two ranges", - result: Some(Value::List { - vals: vec![test_row_1, test_row_2, test_row_3], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![test_row_1, test_row_2, test_row_3], + Span::test_data(), + )), }, Example { example: "glob *.ogg | zip ['bang.ogg', 'fanfare.ogg', 'laser.ogg'] | each {|| mv $in.0 $in.1 }", @@ -99,10 +99,7 @@ impl Command for Zip { Ok(input .into_iter() .zip(other.into_pipeline_data()) - .map(move |(x, y)| Value::List { - vals: vec![x, y], - span: head, - }) + .map(move |(x, y)| Value::list(vec![x, y], head)) .into_pipeline_data(ctrlc) .set_metadata(metadata)) } diff --git a/crates/nu-command/src/formats/from/command.rs b/crates/nu-command/src/formats/from/command.rs index 84a4718d1..c69f14fba 100644 --- a/crates/nu-command/src/formats/from/command.rs +++ b/crates/nu-command/src/formats/from/command.rs @@ -32,16 +32,16 @@ impl Command for From { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &From.signature(), &From.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/formats/from/csv.rs b/crates/nu-command/src/formats/from/csv.rs index 671217ca5..f73676ced 100644 --- a/crates/nu-command/src/formats/from/csv.rs +++ b/crates/nu-command/src/formats/from/csv.rs @@ -81,16 +81,16 @@ impl Command for FromCsv { Example { description: "Convert comma-separated data to a table", example: "\"ColA,ColB\n1,2\" | from csv", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string()], vals: vec![ Value::test_int(1), Value::test_int(2), ], })], - span: Span::test_data(), - }) + Span::test_data(), + )) }, Example { description: "Convert comma-separated data to a table, ignoring headers", diff --git a/crates/nu-command/src/formats/from/delimited.rs b/crates/nu-command/src/formats/from/delimited.rs index ed100cc0c..1a6c63d4b 100644 --- a/crates/nu-command/src/formats/from/delimited.rs +++ b/crates/nu-command/src/formats/from/delimited.rs @@ -38,22 +38,16 @@ fn from_delimited_string_to_value( let mut output_row = vec![]; for value in row?.iter() { if no_infer { - output_row.push(Value::String { - span, - val: value.into(), - }); + output_row.push(Value::string(value.to_string(), span)); continue; } if let Ok(i) = value.parse::() { - output_row.push(Value::Int { val: i, span }); + output_row.push(Value::int(i, span)); } else if let Ok(f) = value.parse::() { - output_row.push(Value::Float { val: f, span }); + output_row.push(Value::float(f, span)); } else { - output_row.push(Value::String { - val: value.into(), - span, - }); + output_row.push(Value::string(value.to_string(), span)); } } rows.push(Value::record( @@ -65,7 +59,7 @@ fn from_delimited_string_to_value( )); } - Ok(Value::List { vals: rows, span }) + Ok(Value::list(rows, span)) } pub(super) struct DelimitedReaderConfig { @@ -96,7 +90,11 @@ pub(super) fn from_delimited_data( pub fn trim_from_str(trim: Option) -> Result { match trim { - Some(Value::String { val: item, span }) => match item.as_str() { + Some(v) => { + let span = v.span(); + match v { + Value::String {val: item, ..} => match item.as_str() { + "all" => Ok(Trim::All), "headers" => Ok(Trim::Headers), "fields" => Ok(Trim::Fields), @@ -107,7 +105,10 @@ pub fn trim_from_str(trim: Option) -> Result { .into(), span, }), - }, + } + _ => Ok(Trim::None), + } + } _ => Ok(Trim::None), } } diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index cada9d866..ceed8e497 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -41,10 +41,10 @@ impl Command for FromJson { cols: vec!["a".to_string(), "b".to_string()], vals: vec![ Value::test_int(1), - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + ), ], })), }, @@ -75,10 +75,7 @@ impl Command for FromJson { } else { match convert_string_to_value(x.to_string(), span) { Ok(v) => Some(v), - Err(error) => Some(Value::Error { - error: Box::new(error), - span, - }), + Err(error) => Some(Value::error(error, span)), } } }) @@ -100,12 +97,12 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value { .map(|x| convert_nujson_to_value(x, span)) .collect(); - Value::List { vals: v, span } + Value::list(v, span) } - nu_json::Value::Bool(b) => Value::Bool { val: *b, span }, - nu_json::Value::F64(f) => Value::Float { val: *f, span }, - nu_json::Value::I64(i) => Value::Int { val: *i, span }, - nu_json::Value::Null => Value::Nothing { span }, + nu_json::Value::Bool(b) => Value::bool(*b, span), + nu_json::Value::F64(f) => Value::float(*f, span), + nu_json::Value::I64(i) => Value::int(*i, span), + nu_json::Value::Null => Value::nothing(span), nu_json::Value::Object(k) => Value::record( k.iter() .map(|(k, v)| (k.clone(), convert_nujson_to_value(v, span))) @@ -114,26 +111,20 @@ fn convert_nujson_to_value(value: &nu_json::Value, span: Span) -> Value { ), nu_json::Value::U64(u) => { if *u > i64::MAX as u64 { - Value::Error { - error: Box::new(ShellError::CantConvert { + Value::error( + ShellError::CantConvert { to_type: "i64 sized integer".into(), from_type: "value larger than i64".into(), span, help: None, - }), + }, span, - } + ) } else { - Value::Int { - val: *u as i64, - span, - } + Value::int(*u as i64, span) } } - nu_json::Value::String(s) => Value::String { - val: s.clone(), - span, - }, + nu_json::Value::String(s) => Value::string(s.clone(), span), } } diff --git a/crates/nu-command/src/formats/from/nuon.rs b/crates/nu-command/src/formats/from/nuon.rs index 24be4721f..8025daa51 100644 --- a/crates/nu-command/src/formats/from/nuon.rs +++ b/crates/nu-command/src/formats/from/nuon.rs @@ -39,10 +39,10 @@ impl Command for FromNuon { cols: vec!["a".to_string(), "b".to_string()], vals: vec![ Value::test_int(1), - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + ), ], })), }, @@ -206,8 +206,8 @@ fn convert_to_value( "closures not supported in nuon".into(), expr.span, )), - Expr::Binary(val) => Ok(Value::Binary { val, span }), - Expr::Bool(val) => Ok(Value::Bool { val, span }), + Expr::Binary(val) => Ok(Value::binary(val, span)), + Expr::Bool(val) => Ok(Value::bool(val, span)), Expr::Call(..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "Error when loading".into(), @@ -220,16 +220,16 @@ fn convert_to_value( "subexpressions and cellpaths not supported in nuon".into(), expr.span, )), - Expr::DateTime(dt) => Ok(Value::Date { val: dt, span }), + Expr::DateTime(dt) => Ok(Value::date(dt, span)), Expr::ExternalCall(..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "Error when loading".into(), "calls not supported in nuon".into(), expr.span, )), - Expr::Filepath(val) => Ok(Value::String { val, span }), - Expr::Directory(val) => Ok(Value::String { val, span }), - Expr::Float(val) => Ok(Value::Float { val, span }), + Expr::Filepath(val) => Ok(Value::string(val, span)), + Expr::Directory(val) => Ok(Value::string(val, span)), + Expr::Float(val) => Ok(Value::float(val, span)), Expr::FullCellPath(full_cell_path) => { if !full_cell_path.tail.is_empty() { Err(ShellError::OutsideSpannedLabeledError( @@ -255,7 +255,7 @@ fn convert_to_value( "extra tokens in input file".into(), expr.span, )), - Expr::GlobPattern(val) => Ok(Value::String { val, span }), + Expr::GlobPattern(val) => Ok(Value::string(val, span)), Expr::ImportPattern(..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "Error when loading".into(), @@ -268,7 +268,7 @@ fn convert_to_value( "overlays not supported in nuon".into(), expr.span, )), - Expr::Int(val) => Ok(Value::Int { val, span }), + Expr::Int(val) => Ok(Value::int(val, span)), Expr::Keyword(kw, ..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "Error when loading".into(), @@ -281,7 +281,7 @@ fn convert_to_value( output.push(convert_to_value(val, span, original_text)?); } - Ok(Value::List { vals: output, span }) + Ok(Value::list(output, span)) } Expr::MatchBlock(..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), @@ -289,7 +289,7 @@ fn convert_to_value( "match blocks not supported in nuon".into(), expr.span, )), - Expr::Nothing => Ok(Value::Nothing { span }), + Expr::Nothing => Ok(Value::nothing(span)), Expr::Operator(..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "Error when loading".into(), @@ -300,25 +300,25 @@ fn convert_to_value( let from = if let Some(f) = from { convert_to_value(*f, span, original_text)? } else { - Value::Nothing { span: expr.span } + Value::nothing(expr.span) }; let next = if let Some(s) = next { convert_to_value(*s, span, original_text)? } else { - Value::Nothing { span: expr.span } + Value::nothing(expr.span) }; let to = if let Some(t) = to { convert_to_value(*t, span, original_text)? } else { - Value::Nothing { span: expr.span } + Value::nothing(expr.span) }; - Ok(Value::Range { - val: Box::new(Range::new(expr.span, from, next, to, &operator)?), - span: expr.span, - }) + Ok(Value::range( + Range::new(expr.span, from, next, to, &operator)?, + expr.span, + )) } Expr::Record(key_vals) => { let mut record = Record::new(); @@ -355,7 +355,7 @@ fn convert_to_value( "signatures not supported in nuon".into(), expr.span, )), - Expr::String(s) => Ok(Value::String { val: s, span }), + Expr::String(s) => Ok(Value::string(s, span)), Expr::StringInterpolation(..) => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "Error when loading".into(), @@ -414,7 +414,7 @@ fn convert_to_value( )); } - Ok(Value::List { vals: output, span }) + Ok(Value::list(output, span)) } Expr::ValueWithUnit(val, unit) => { let size = match val.expr { @@ -430,80 +430,41 @@ fn convert_to_value( }; match unit.item { - Unit::Byte => Ok(Value::Filesize { val: size, span }), - Unit::Kilobyte => Ok(Value::Filesize { - val: size * 1000, + Unit::Byte => Ok(Value::filesize(size, span)), + Unit::Kilobyte => Ok(Value::filesize(size * 1000, span)), + Unit::Megabyte => Ok(Value::filesize(size * 1000 * 1000, span)), + Unit::Gigabyte => Ok(Value::filesize(size * 1000 * 1000 * 1000, span)), + Unit::Terabyte => Ok(Value::filesize(size * 1000 * 1000 * 1000 * 1000, span)), + Unit::Petabyte => Ok(Value::filesize( + size * 1000 * 1000 * 1000 * 1000 * 1000, span, - }), - Unit::Megabyte => Ok(Value::Filesize { - val: size * 1000 * 1000, + )), + Unit::Exabyte => Ok(Value::filesize( + size * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, span, - }), - Unit::Gigabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000, - span, - }), - Unit::Terabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000 * 1000, - span, - }), - Unit::Petabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000 * 1000 * 1000, - span, - }), - Unit::Exabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, - span, - }), + )), - Unit::Kibibyte => Ok(Value::Filesize { - val: size * 1024, + Unit::Kibibyte => Ok(Value::filesize(size * 1024, span)), + Unit::Mebibyte => Ok(Value::filesize(size * 1024 * 1024, span)), + Unit::Gibibyte => Ok(Value::filesize(size * 1024 * 1024 * 1024, span)), + Unit::Tebibyte => Ok(Value::filesize(size * 1024 * 1024 * 1024 * 1024, span)), + Unit::Pebibyte => Ok(Value::filesize( + size * 1024 * 1024 * 1024 * 1024 * 1024, span, - }), - Unit::Mebibyte => Ok(Value::Filesize { - val: size * 1024 * 1024, + )), + Unit::Exbibyte => Ok(Value::filesize( + size * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, span, - }), - Unit::Gibibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024, - span, - }), - Unit::Tebibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024 * 1024, - span, - }), - Unit::Pebibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024 * 1024 * 1024, - span, - }), - Unit::Exbibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, - span, - }), + )), - Unit::Nanosecond => Ok(Value::Duration { val: size, span }), - Unit::Microsecond => Ok(Value::Duration { - val: size * 1000, - span, - }), - Unit::Millisecond => Ok(Value::Duration { - val: size * 1000 * 1000, - span, - }), - Unit::Second => Ok(Value::Duration { - val: size * 1000 * 1000 * 1000, - span, - }), - Unit::Minute => Ok(Value::Duration { - val: size * 1000 * 1000 * 1000 * 60, - span, - }), - Unit::Hour => Ok(Value::Duration { - val: size * 1000 * 1000 * 1000 * 60 * 60, - span, - }), + Unit::Nanosecond => Ok(Value::duration(size, span)), + Unit::Microsecond => Ok(Value::duration(size * 1000, span)), + Unit::Millisecond => Ok(Value::duration(size * 1000 * 1000, span)), + Unit::Second => Ok(Value::duration(size * 1000 * 1000 * 1000, span)), + Unit::Minute => Ok(Value::duration(size * 1000 * 1000 * 1000 * 60, span)), + Unit::Hour => Ok(Value::duration(size * 1000 * 1000 * 1000 * 60 * 60, span)), Unit::Day => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24) { - Some(val) => Ok(Value::Duration { val, span }), + Some(val) => Ok(Value::duration(val, span)), None => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "day duration too large".into(), @@ -513,7 +474,7 @@ fn convert_to_value( }, Unit::Week => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24 * 7) { - Some(val) => Ok(Value::Duration { val, span }), + Some(val) => Ok(Value::duration(val, span)), None => Err(ShellError::OutsideSpannedLabeledError( original_text.to_string(), "week duration too large".into(), diff --git a/crates/nu-command/src/formats/from/ods.rs b/crates/nu-command/src/formats/from/ods.rs index fea867a76..40d6be371 100644 --- a/crates/nu-command/src/formats/from/ods.rs +++ b/crates/nu-command/src/formats/from/ods.rs @@ -158,13 +158,7 @@ fn from_ods( sheet_output.push(Value::record(record, head)); } - dict.insert( - sheet_name, - Value::List { - vals: sheet_output, - span: head, - }, - ); + dict.insert(sheet_name, Value::list(sheet_output, head)); } else { return Err(ShellError::UnsupportedInput( "Could not load sheet".to_string(), diff --git a/crates/nu-command/src/formats/from/ssv.rs b/crates/nu-command/src/formats/from/ssv.rs index 9abea4e5b..cfd184551 100644 --- a/crates/nu-command/src/formats/from/ssv.rs +++ b/crates/nu-command/src/formats/from/ssv.rs @@ -44,20 +44,20 @@ impl Command for FromSsv { example: r#"'FOO BAR 1 2' | from ssv"#, description: "Converts ssv formatted string to table", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["FOO".to_string(), "BAR".to_string()], vals: vec![Value::test_string("1"), Value::test_string("2")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { example: r#"'FOO BAR 1 2' | from ssv -n"#, description: "Converts ssv formatted string to table but not treating the first row as column names", result: Some( - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_record(Record { cols: vec!["column1".to_string(), "column2".to_string()], vals: vec![Value::test_string("FOO"), Value::test_string("BAR")], @@ -67,8 +67,8 @@ impl Command for FromSsv { vals: vec![Value::test_string("1"), Value::test_string("2")], }), ], - span: Span::test_data(), - } + Span::test_data(), + ) ), }] } @@ -280,7 +280,7 @@ fn from_ssv_string_to_value( }) .collect(); - Value::List { vals: rows, span } + Value::list(rows, span) } fn from_ssv( diff --git a/crates/nu-command/src/formats/from/toml.rs b/crates/nu-command/src/formats/from/toml.rs index 4a289b68b..073291891 100644 --- a/crates/nu-command/src/formats/from/toml.rs +++ b/crates/nu-command/src/formats/from/toml.rs @@ -41,10 +41,10 @@ b = [1, 2]' | from toml", cols: vec!["a".to_string(), "b".to_string()], vals: vec![ Value::test_int(1), - Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + ), ], })), }, @@ -73,25 +73,19 @@ fn convert_toml_to_value(value: &toml::Value, span: Span) -> Value { .map(|x| convert_toml_to_value(x, span)) .collect(); - Value::List { vals: v, span } + Value::list(v, span) } - toml::Value::Boolean(b) => Value::Bool { val: *b, span }, - toml::Value::Float(f) => Value::Float { val: *f, span }, - toml::Value::Integer(i) => Value::Int { val: *i, span }, + toml::Value::Boolean(b) => Value::bool(*b, span), + toml::Value::Float(f) => Value::float(*f, span), + toml::Value::Integer(i) => Value::int(*i, span), toml::Value::Table(k) => Value::record( k.iter() .map(|(k, v)| (k.clone(), convert_toml_to_value(v, span))) .collect(), span, ), - toml::Value::String(s) => Value::String { - val: s.clone(), - span, - }, - toml::Value::Datetime(d) => Value::String { - val: d.to_string(), - span, - }, + toml::Value::String(s) => Value::string(s.clone(), span), + toml::Value::Datetime(d) => Value::string(d.to_string(), span), } } diff --git a/crates/nu-command/src/formats/from/tsv.rs b/crates/nu-command/src/formats/from/tsv.rs index f649a5c71..637c1224b 100644 --- a/crates/nu-command/src/formats/from/tsv.rs +++ b/crates/nu-command/src/formats/from/tsv.rs @@ -75,16 +75,16 @@ impl Command for FromTsv { Example { description: "Convert tab-separated data to a table", example: "\"ColA\tColB\n1\t2\" | from tsv", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string()], vals: vec![ Value::test_int(1), Value::test_int(2), ], })], - span: Span::test_data(), - }) + Span::test_data(), + )) }, Example { description: "Create a tsv file with header columns and open it", diff --git a/crates/nu-command/src/formats/from/xlsx.rs b/crates/nu-command/src/formats/from/xlsx.rs index 28d040618..2974688a5 100644 --- a/crates/nu-command/src/formats/from/xlsx.rs +++ b/crates/nu-command/src/formats/from/xlsx.rs @@ -157,13 +157,7 @@ fn from_xlsx( sheet_output.push(Value::record(record, head)); } - dict.insert( - sheet_name, - Value::List { - vals: sheet_output, - span: head, - }, - ); + dict.insert(sheet_name, Value::list(sheet_output, head)); } else { return Err(ShellError::UnsupportedInput( "Could not load sheet".to_string(), diff --git a/crates/nu-command/src/formats/from/xml.rs b/crates/nu-command/src/formats/from/xml.rs index fc7fd9357..f42acfeb4 100644 --- a/crates/nu-command/src/formats/from/xml.rs +++ b/crates/nu-command/src/formats/from/xml.rs @@ -336,10 +336,7 @@ mod tests { } fn table(list: &[Value]) -> Value { - Value::List { - vals: list.to_vec(), - span: Span::test_data(), - } + Value::list(list.to_vec(), Span::test_data()) } fn content_tag( diff --git a/crates/nu-command/src/formats/from/yaml.rs b/crates/nu-command/src/formats/from/yaml.rs index d8c80f723..ea85f74d1 100644 --- a/crates/nu-command/src/formats/from/yaml.rs +++ b/crates/nu-command/src/formats/from/yaml.rs @@ -88,28 +88,20 @@ fn convert_yaml_value_to_nu_value( val_span, ); Ok(match v { - serde_yaml::Value::Bool(b) => Value::Bool { val: *b, span }, - serde_yaml::Value::Number(n) if n.is_i64() => Value::Int { - val: n.as_i64().ok_or(err_not_compatible_number)?, - span, - }, - serde_yaml::Value::Number(n) if n.is_f64() => Value::Float { - val: n.as_f64().ok_or(err_not_compatible_number)?, - span, - }, - serde_yaml::Value::String(s) => Value::String { - val: s.to_string(), - span, - }, + serde_yaml::Value::Bool(b) => Value::bool(*b, span), + serde_yaml::Value::Number(n) if n.is_i64() => { + Value::int(n.as_i64().ok_or(err_not_compatible_number)?, span) + } + serde_yaml::Value::Number(n) if n.is_f64() => { + Value::float(n.as_f64().ok_or(err_not_compatible_number)?, span) + } + serde_yaml::Value::String(s) => Value::string(s.to_string(), span), serde_yaml::Value::Sequence(a) => { let result: Result, ShellError> = a .iter() .map(|x| convert_yaml_value_to_nu_value(x, span, val_span)) .collect(); - Value::List { - vals: result?, - span, - } + Value::list(result?, span) } serde_yaml::Value::Mapping(t) => { // Using an IndexMap ensures consistent ordering @@ -155,10 +147,7 @@ fn convert_yaml_value_to_nu_value( .first() .and_then(|e| match e { (serde_yaml::Value::String(s), serde_yaml::Value::Null) => { - Some(Value::String { - val: "{{ ".to_owned() + s.as_str() + " }}", - span, - }) + Some(Value::string("{{ ".to_owned() + s.as_str() + " }}", span)) } _ => None, }) @@ -177,19 +166,19 @@ fn convert_yaml_value_to_nu_value( let value = match &t.value { serde_yaml::Value::String(s) => { let val = format!("{} {}", tag, s).trim().to_string(); - Value::String { val, span } + Value::string(val, span) } serde_yaml::Value::Number(n) => { let val = format!("{} {}", tag, n).trim().to_string(); - Value::String { val, span } + Value::string(val, span) } serde_yaml::Value::Bool(b) => { let val = format!("{} {}", tag, b).trim().to_string(); - Value::String { val, span } + Value::string(val, span) } serde_yaml::Value::Null => { let val = format!("{}", tag).trim().to_string(); - Value::String { val, span } + Value::string(val, span) } v => convert_yaml_value_to_nu_value(v, span, val_span)?, }; @@ -223,10 +212,7 @@ pub fn from_yaml_string_to_value( match documents.len() { 0 => Ok(Value::nothing(span)), 1 => Ok(documents.remove(0)), - _ => Ok(Value::List { - vals: documents, - span, - }), + _ => Ok(Value::list(documents, span)), } } @@ -243,22 +229,22 @@ pub fn get_examples() -> Vec> { Example { example: "'[ a: 1, b: [1, 2] ]' | from yaml", description: "Converts yaml formatted string to table", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string()], vals: vec![Value::test_int(1)], }), Value::test_record(Record { cols: vec!["b".to_string()], - vals: vec![Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }], + vals: vec![Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -349,8 +335,8 @@ mod test { Span::test_data(), ); - let expected: Result = Ok(Value::List { - vals: vec![ + let expected: Result = Ok(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![Value::test_string("b"), Value::test_string("c")], @@ -360,8 +346,8 @@ mod test { vals: vec![Value::test_string("g"), Value::test_string("h")], }), ], - span: Span::test_data(), - }); + Span::test_data(), + )); // Unfortunately the eq function for Value doesn't compare well enough to detect // ordering errors in List columns or values. diff --git a/crates/nu-command/src/formats/to/command.rs b/crates/nu-command/src/formats/to/command.rs index a4f21fde9..1e15c97c8 100644 --- a/crates/nu-command/src/formats/to/command.rs +++ b/crates/nu-command/src/formats/to/command.rs @@ -32,16 +32,16 @@ impl Command for To { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &To.signature(), &To.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/formats/to/delimited.rs b/crates/nu-command/src/formats/to/delimited.rs index e906c390d..752630762 100644 --- a/crates/nu-command/src/formats/to/delimited.rs +++ b/crates/nu-command/src/formats/to/delimited.rs @@ -10,9 +10,10 @@ fn from_value_to_delimited_string( config: &Config, head: Span, ) -> Result { + let span = value.span(); match value { - Value::Record { val, span } => record_to_delimited(val, *span, separator, config, head), - Value::List { vals, span } => table_to_delimited(vals, *span, separator, config, head), + Value::Record { val, .. } => record_to_delimited(val, span, separator, config, head), + Value::List { vals, .. } => table_to_delimited(vals, span, separator, config, head), // Propagate errors by explicitly matching them before the final case. Value::Error { error, .. } => Err(*error.clone()), v => Err(make_unsupported_input_error(v, head, v.span())), diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 4426a4f8c..e7f748aa1 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -64,20 +64,18 @@ impl Command for ToJson { }; match json_result { - Ok(serde_json_string) => Ok(Value::String { - val: serde_json_string, - span, + Ok(serde_json_string) => { + Ok(Value::string(serde_json_string, span).into_pipeline_data()) } - .into_pipeline_data()), - _ => Ok(Value::Error { - error: Box::new(ShellError::CantConvert { + _ => Ok(Value::error( + ShellError::CantConvert { to_type: "JSON".into(), from_type: value.get_type().to_string(), span, help: None, - }), + }, span, - } + ) .into_pipeline_data()), } } @@ -107,6 +105,7 @@ impl Command for ToJson { } pub fn value_to_json_value(v: &Value) -> Result { + let span = v.span(); Ok(match v { Value::Bool { val, .. } => nu_json::Value::Bool(*val), Value::Filesize { val, .. } => nu_json::Value::I64(*val), @@ -146,8 +145,8 @@ pub fn value_to_json_value(v: &Value) -> Result { let collected = val.collect()?; value_to_json_value(&collected)? } - Value::CustomValue { val, span } => { - let collected = val.to_base_value(*span)?; + Value::CustomValue { val, .. } => { + let collected = val.to_base_value(span)?; value_to_json_value(&collected)? } }) diff --git a/crates/nu-command/src/formats/to/md.rs b/crates/nu-command/src/formats/to/md.rs index 192650deb..c72ef0540 100644 --- a/crates/nu-command/src/formats/to/md.rs +++ b/crates/nu-command/src/formats/to/md.rs @@ -161,9 +161,10 @@ fn table(input: PipelineData, pretty: bool, config: &Config) -> String { for row in vec_of_values { let mut escaped_row: Vec = Vec::new(); + let span = row.span(); match row.to_owned() { - Value::Record { span, .. } => { + Value::Record { .. } => { for i in 0..headers.len() { let data = row.get_data_by_key(&headers[i]); let value_string = data @@ -224,23 +225,13 @@ pub fn group_by(values: PipelineData, head: Span, config: &Config) -> (PipelineD if value.len() == 1 { output.push(value.pop().unwrap_or_else(|| Value::nothing(head))) } else { - output.push(Value::List { - vals: value.to_vec(), - span: head, - }) + output.push(Value::list(value.to_vec(), head)) } } if output.len() == 1 { single_list = true; } - ( - Value::List { - vals: output, - span: head, - } - .into_pipeline_data(), - single_list, - ) + (Value::list(output, head).into_pipeline_data(), single_list) } fn get_output_string( @@ -391,8 +382,8 @@ mod tests { #[test] fn render_table() { - let value = Value::List { - vals: vec![ + let value = Value::list( + vec![ Value::test_record(Record { cols: vec!["country".to_string()], vals: vec![Value::test_string("Ecuador")], @@ -406,8 +397,8 @@ mod tests { vals: vec![Value::test_string("USA")], }), ], - span: Span::test_data(), - }; + Span::test_data(), + ); assert_eq!( table( diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs index acdefcb29..213c9bec0 100644 --- a/crates/nu-command/src/formats/to/nuon.rs +++ b/crates/nu-command/src/formats/to/nuon.rs @@ -73,20 +73,18 @@ impl Command for ToNuon { }; match nuon_result { - Ok(serde_nuon_string) => Ok(Value::String { - val: serde_nuon_string, - span, + Ok(serde_nuon_string) => { + Ok(Value::string(serde_nuon_string, span).into_pipeline_data()) } - .into_pipeline_data()), - _ => Ok(Value::Error { - error: Box::new(ShellError::CantConvert { + _ => Ok(Value::error( + ShellError::CantConvert { to_type: "NUON".into(), from_type: value.get_type().to_string(), span, help: None, - }), + }, span, - } + ) .into_pipeline_data()), } } diff --git a/crates/nu-command/src/formats/to/text.rs b/crates/nu-command/src/formats/to/text.rs index 4ce19b475..cb3092d45 100644 --- a/crates/nu-command/src/formats/to/text.rs +++ b/crates/nu-command/src/formats/to/text.rs @@ -64,11 +64,7 @@ impl Command for ToText { // Even if the data is collected when it arrives at `to text`, we should be able to stream it out let collected_input = local_into_string(input.into_value(span), line_ending, config); - Ok(Value::String { - val: collected_input, - span, - } - .into_pipeline_data()) + Ok(Value::string(collected_input, span).into_pipeline_data()) } } diff --git a/crates/nu-command/src/formats/to/toml.rs b/crates/nu-command/src/formats/to/toml.rs index 0b9e8e176..a67f384e4 100644 --- a/crates/nu-command/src/formats/to/toml.rs +++ b/crates/nu-command/src/formats/to/toml.rs @@ -45,6 +45,7 @@ impl Command for ToToml { // Helper method to recursively convert nu_protocol::Value -> toml::Value // This shouldn't be called at the top-level fn helper(engine_state: &EngineState, v: &Value) -> Result { + let span = v.span(); Ok(match &v { Value::Bool { val, .. } => toml::Value::Boolean(*val), Value::Int { val, .. } => toml::Value::Integer(*val), @@ -66,13 +67,13 @@ fn helper(engine_state: &EngineState, v: &Value) -> Result toml::Value::Array(toml_list(engine_state, vals)?), - Value::Block { span, .. } => { - let code = engine_state.get_span_contents(*span); + Value::Block { .. } => { + let code = engine_state.get_span_contents(span); let code = String::from_utf8_lossy(code).to_string(); toml::Value::String(code) } - Value::Closure { span, .. } => { - let code = engine_state.get_span_contents(*span); + Value::Closure { .. } => { + let code = engine_state.get_span_contents(span); let code = String::from_utf8_lossy(code).to_string(); toml::Value::String(code) } @@ -113,20 +114,16 @@ fn toml_into_pipeline_data( span: Span, ) -> Result { match toml::to_string(&toml_value) { - Ok(serde_toml_string) => Ok(Value::String { - val: serde_toml_string, - span, - } - .into_pipeline_data()), - _ => Ok(Value::Error { - error: Box::new(ShellError::CantConvert { + Ok(serde_toml_string) => Ok(Value::string(serde_toml_string, span).into_pipeline_data()), + _ => Ok(Value::error( + ShellError::CantConvert { to_type: "TOML".into(), from_type: value_type.to_string(), span, help: None, - }), + }, span, - } + ) .into_pipeline_data()), } } @@ -194,10 +191,10 @@ mod tests { m.insert("is".to_owned(), Value::nothing(Span::test_data())); m.insert( "features".to_owned(), - Value::List { - vals: vec![Value::test_string("hello"), Value::test_string("array")], - span: Span::test_data(), - }, + Value::list( + vec![Value::test_string("hello"), Value::test_string("array")], + Span::test_data(), + ), ); let tv = value_to_toml_value( &engine_state, @@ -223,10 +220,7 @@ mod tests { .expect_err("Expected non-valid toml (String) to cause error!"); value_to_toml_value( &engine_state, - &Value::List { - vals: vec![Value::test_string("1")], - span: Span::test_data(), - }, + &Value::list(vec![Value::test_string("1")], Span::test_data()), Span::test_data(), ) .expect_err("Expected non-valid toml (Table) to cause error!"); diff --git a/crates/nu-command/src/formats/to/xml.rs b/crates/nu-command/src/formats/to/xml.rs index 57663b0b9..11a4ce65e 100644 --- a/crates/nu-command/src/formats/to/xml.rs +++ b/crates/nu-command/src/formats/to/xml.rs @@ -98,14 +98,15 @@ fn to_xml_entry( writer: &mut quick_xml::Writer, ) -> Result<(), ShellError> { let entry_span = entry.span(); + let span = entry.span(); // Allow using strings directly as content. // So user can write // {tag: a content: ['qwe']} // instead of longer // {tag: a content: [{content: 'qwe'}]} - if let (Value::String { val, span }, false) = (&entry, top_level) { - return to_xml_text(val.as_str(), *span, writer); + if let (Value::String { val, .. }, false) = (&entry, top_level) { + return to_xml_text(val.as_str(), span, writer); } if !matches!(entry, Value::Record { .. }) { @@ -130,8 +131,10 @@ fn to_xml_entry( .get_data_by_key(COLUMN_CONTENT_NAME) .unwrap_or_else(|| Value::nothing(Span::unknown())); + let content_span = content.span(); + let tag_span = tag.span(); match (tag, attrs, content) { - (Value::Nothing { .. }, Value::Nothing { .. }, Value::String { val, span }) => { + (Value::Nothing { .. }, Value::Nothing { .. }, Value::String { val, .. }) => { // Strings can not appear on top level of document if top_level { return Err(ShellError::CantConvert { @@ -141,16 +144,9 @@ fn to_xml_entry( help: Some("Strings can not be a root element of document".into()), }); } - to_xml_text(val.as_str(), span, writer) + to_xml_text(val.as_str(), content_span, writer) } - ( - Value::String { - val: tag_name, - span: tag_span, - }, - attrs, - children, - ) => to_tag_like( + (Value::String { val: tag_name, .. }, attrs, children) => to_tag_like( entry_span, tag_name, tag_span, attrs, children, top_level, writer, ), _ => Ok(()), diff --git a/crates/nu-command/src/formats/to/yaml.rs b/crates/nu-command/src/formats/to/yaml.rs index a6fee7450..099d1d5da 100644 --- a/crates/nu-command/src/formats/to/yaml.rs +++ b/crates/nu-command/src/formats/to/yaml.rs @@ -106,20 +106,16 @@ fn to_yaml(input: PipelineData, head: Span) -> Result let yaml_value = value_to_yaml_value(&value)?; match serde_yaml::to_string(&yaml_value) { - Ok(serde_yaml_string) => Ok(Value::String { - val: serde_yaml_string, - span: head, - } - .into_pipeline_data()), - _ => Ok(Value::Error { - error: Box::new(ShellError::CantConvert { + Ok(serde_yaml_string) => Ok(Value::string(serde_yaml_string, head).into_pipeline_data()), + _ => Ok(Value::error( + ShellError::CantConvert { to_type: "YAML".into(), from_type: value.get_type().to_string(), span: head, help: None, - }), - span: head, - } + }, + head, + ) .into_pipeline_data()), } } diff --git a/crates/nu-command/src/generators/cal.rs b/crates/nu-command/src/generators/cal.rs index 711de8358..4af2dd0a4 100644 --- a/crates/nu-command/src/generators/cal.rs +++ b/crates/nu-command/src/generators/cal.rs @@ -134,11 +134,7 @@ pub fn cal( current_day_option, )?; - Ok(Value::List { - vals: calendar_vec_deque.into_iter().collect(), - span: tag, - } - .into_pipeline_data()) + Ok(Value::list(calendar_vec_deque.into_iter().collect(), tag).into_pipeline_data()) } fn get_invalid_year_shell_error(head: Span) -> ShellError { @@ -324,10 +320,7 @@ fn add_month_to_table( if should_show_month_column || should_show_month_names { let month_value = if should_show_month_names { - Value::String { - val: month_helper.month_name.clone(), - span: tag, - } + Value::string(month_helper.month_name.clone(), tag) } else { Value::int(month_helper.selected_month as i64, tag) }; @@ -339,7 +332,7 @@ fn add_month_to_table( let should_add_day_number_to_table = (day_number > total_start_offset) && (day_number <= day_limit); - let mut value = Value::Nothing { span: tag }; + let mut value = Value::nothing(tag); if should_add_day_number_to_table { let adjusted_day_number = day_number - total_start_offset; diff --git a/crates/nu-command/src/generators/seq.rs b/crates/nu-command/src/generators/seq.rs index d3b742686..b44ce63f3 100644 --- a/crates/nu-command/src/generators/seq.rs +++ b/crates/nu-command/src/generators/seq.rs @@ -40,8 +40,8 @@ impl Command for Seq { Example { description: "sequence 1 to 10", example: "seq 1 10", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(1), Value::test_int(2), Value::test_int(3), @@ -53,14 +53,14 @@ impl Command for Seq { Value::test_int(9), Value::test_int(10), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "sequence 1.0 to 2.0 by 0.1s", example: "seq 1.0 0.1 2.0", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_float(1.0000), Value::test_float(1.1000), Value::test_float(1.2000), @@ -73,8 +73,8 @@ impl Command for Seq { Value::test_float(1.9000), Value::test_float(2.0000), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "sequence 1 to 5, then convert to a string with a pipe separator", diff --git a/crates/nu-command/src/generators/seq_char.rs b/crates/nu-command/src/generators/seq_char.rs index 8529008f2..00dfb3257 100644 --- a/crates/nu-command/src/generators/seq_char.rs +++ b/crates/nu-command/src/generators/seq_char.rs @@ -38,16 +38,16 @@ impl Command for SeqChar { Example { description: "sequence a to e", example: "seq char a e", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string('a'), Value::test_string('b'), Value::test_string('c'), Value::test_string('d'), Value::test_string('e'), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "sequence a to e, and put the characters in a pipe-separated string", @@ -127,9 +127,9 @@ fn run_seq_char(start_ch: char, end_ch: char, span: Span) -> Result>(); - Ok(Value::List { vals: result, span }.into_pipeline_data()) + Ok(Value::list(result, span).into_pipeline_data()) } #[cfg(test)] diff --git a/crates/nu-command/src/generators/seq_date.rs b/crates/nu-command/src/generators/seq_date.rs index 79c6e936d..6f2df0d06 100644 --- a/crates/nu-command/src/generators/seq_date.rs +++ b/crates/nu-command/src/generators/seq_date.rs @@ -78,8 +78,8 @@ impl Command for SeqDate { Example { description: "print the first 10 days in January, 2020", example: "seq date -b '2020-01-01' -e '2020-01-10'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("2020-01-01"), Value::test_string("2020-01-02"), Value::test_string("2020-01-03"), @@ -91,14 +91,14 @@ impl Command for SeqDate { Value::test_string("2020-01-09"), Value::test_string("2020-01-10"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "print every fifth day between January 1st 2020 and January 31st 2020", example: "seq date -b '2020-01-01' -e '2020-01-31' -n 5", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("2020-01-01"), Value::test_string("2020-01-06"), Value::test_string("2020-01-11"), @@ -107,8 +107,8 @@ impl Command for SeqDate { Value::test_string("2020-01-26"), Value::test_string("2020-01-31"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -324,10 +324,7 @@ pub fn run_seq_dates( } } - Ok(Value::List { - vals: ret, - span: call_span, - }) + Ok(Value::list(ret, call_span)) } #[cfg(test)] diff --git a/crates/nu-command/src/hash/generic_digest.rs b/crates/nu-command/src/hash/generic_digest.rs index cbbe4b105..ba43fc365 100644 --- a/crates/nu-command/src/hash/generic_digest.rs +++ b/crates/nu-command/src/hash/generic_digest.rs @@ -107,15 +107,15 @@ where Ok(v @ Value::Error { .. }) => return Ok(v.into_pipeline_data()), // Unsupported data Ok(other) => { - return Ok(Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + return Ok(Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string and binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - } + ) .into_pipeline_data()); } Err(err) => return Err(err), @@ -123,17 +123,9 @@ where } let digest = hasher.finalize(); if args.binary { - Ok(Value::Binary { - val: digest.to_vec(), - span, - } - .into_pipeline_data()) + Ok(Value::binary(digest.to_vec(), span).into_pipeline_data()) } else { - Ok(Value::String { - val: format!("{digest:x}"), - span, - } - .into_pipeline_data()) + Ok(Value::string(format!("{digest:x}"), span).into_pipeline_data()) } } _ => operate( @@ -152,37 +144,32 @@ where D: HashDigest, digest::Output: core::fmt::LowerHex, { + let span = input.span(); let (bytes, span) = match input { - Value::String { val, span } => (val.as_bytes(), *span), - Value::Binary { val, span } => (val.as_slice(), *span), + Value::String { val, .. } => (val.as_bytes(), span), + Value::Binary { val, .. } => (val.as_slice(), span), // Propagate existing errors Value::Error { .. } => return input.clone(), other => { let span = input.span(); - return Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + return Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string or binary".into(), wrong_type: other.get_type().to_string(), dst_span: span, src_span: other.span(), - }), + }, span, - }; + ); } }; let digest = D::digest(bytes); if args.binary { - Value::Binary { - val: digest.to_vec(), - span, - } + Value::binary(digest.to_vec(), span) } else { - Value::String { - val: format!("{digest:x}"), - span, - } + Value::string(format!("{digest:x}"), span) } } diff --git a/crates/nu-command/src/hash/hash_.rs b/crates/nu-command/src/hash/hash_.rs index 4882dd92d..0c56668ea 100644 --- a/crates/nu-command/src/hash/hash_.rs +++ b/crates/nu-command/src/hash/hash_.rs @@ -32,16 +32,16 @@ impl Command for Hash { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Self.signature(), &Self.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/hash/md5.rs b/crates/nu-command/src/hash/md5.rs index 0c1238174..41237f3cd 100644 --- a/crates/nu-command/src/hash/md5.rs +++ b/crates/nu-command/src/hash/md5.rs @@ -14,21 +14,21 @@ impl HashDigest for Md5 { Example { description: "Return the md5 hash of a string, hex-encoded", example: "'abcdefghijklmnopqrstuvwxyz' | hash md5", - result: Some(Value::String { - val: "c3fcd3d76192e4007dfb496cca67e13b".to_owned(), - span: Span::test_data(), - }), + result: Some(Value::string( + "c3fcd3d76192e4007dfb496cca67e13b".to_owned(), + Span::test_data(), + )), }, Example { description: "Return the md5 hash of a string, as binary", example: "'abcdefghijklmnopqrstuvwxyz' | hash md5 --binary", - result: Some(Value::Binary { - val: vec![ + result: Some(Value::binary( + vec![ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b, ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Return the md5 hash of a file's contents", @@ -51,14 +51,11 @@ mod tests { #[test] fn hash_string() { - let binary = Value::String { - val: "abcdefghijklmnopqrstuvwxyz".to_owned(), - span: Span::test_data(), - }; - let expected = Value::String { - val: "c3fcd3d76192e4007dfb496cca67e13b".to_owned(), - span: Span::test_data(), - }; + let binary = Value::string("abcdefghijklmnopqrstuvwxyz".to_owned(), Span::test_data()); + let expected = Value::string( + "c3fcd3d76192e4007dfb496cca67e13b".to_owned(), + Span::test_data(), + ); let actual = generic_digest::action::( &binary, &Arguments { @@ -72,14 +69,11 @@ mod tests { #[test] fn hash_bytes() { - let binary = Value::Binary { - val: vec![0xC0, 0xFF, 0xEE], - span: Span::test_data(), - }; - let expected = Value::String { - val: "5f80e231382769b0102b1164cf722d83".to_owned(), - span: Span::test_data(), - }; + let binary = Value::binary(vec![0xC0, 0xFF, 0xEE], Span::test_data()); + let expected = Value::string( + "5f80e231382769b0102b1164cf722d83".to_owned(), + Span::test_data(), + ); let actual = generic_digest::action::( &binary, &Arguments { diff --git a/crates/nu-command/src/hash/sha256.rs b/crates/nu-command/src/hash/sha256.rs index 08bebe2db..bcd82b4b9 100644 --- a/crates/nu-command/src/hash/sha256.rs +++ b/crates/nu-command/src/hash/sha256.rs @@ -14,23 +14,22 @@ impl HashDigest for Sha256 { Example { description: "Return the sha256 hash of a string, hex-encoded", example: "'abcdefghijklmnopqrstuvwxyz' | hash sha256", - result: Some(Value::String { - val: "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73" - .to_owned(), - span: Span::test_data(), - }), + result: Some(Value::string( + "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73".to_owned(), + Span::test_data(), + )), }, Example { description: "Return the sha256 hash of a string, as binary", example: "'abcdefghijklmnopqrstuvwxyz' | hash sha256 --binary", - result: Some(Value::Binary { - val: vec![ + result: Some(Value::binary( + vec![ 0x71, 0xc4, 0x80, 0xdf, 0x93, 0xd6, 0xae, 0x2f, 0x1e, 0xfa, 0xd1, 0x44, 0x7c, 0x66, 0xc9, 0x52, 0x5e, 0x31, 0x62, 0x18, 0xcf, 0x51, 0xfc, 0x8d, 0x9e, 0xd8, 0x32, 0xf2, 0xda, 0xf1, 0x8b, 0x73, ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Return the sha256 hash of a file's contents", @@ -53,14 +52,11 @@ mod tests { #[test] fn hash_string() { - let binary = Value::String { - val: "abcdefghijklmnopqrstuvwxyz".to_owned(), - span: Span::test_data(), - }; - let expected = Value::String { - val: "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73".to_owned(), - span: Span::test_data(), - }; + let binary = Value::string("abcdefghijklmnopqrstuvwxyz".to_owned(), Span::test_data()); + let expected = Value::string( + "71c480df93d6ae2f1efad1447c66c9525e316218cf51fc8d9ed832f2daf18b73".to_owned(), + Span::test_data(), + ); let actual = generic_digest::action::( &binary, &Arguments { @@ -74,14 +70,11 @@ mod tests { #[test] fn hash_bytes() { - let binary = Value::Binary { - val: vec![0xC0, 0xFF, 0xEE], - span: Span::test_data(), - }; - let expected = Value::String { - val: "c47a10dc272b1221f0380a2ae0f7d7fa830b3e378f2f5309bbf13f61ad211913".to_owned(), - span: Span::test_data(), - }; + let binary = Value::binary(vec![0xC0, 0xFF, 0xEE], Span::test_data()); + let expected = Value::string( + "c47a10dc272b1221f0380a2ae0f7d7fa830b3e378f2f5309bbf13f61ad211913".to_owned(), + Span::test_data(), + ); let actual = generic_digest::action::( &binary, &Arguments { diff --git a/crates/nu-command/src/help/help_.rs b/crates/nu-command/src/help/help_.rs index 765934d54..74351f031 100644 --- a/crates/nu-command/src/help/help_.rs +++ b/crates/nu-command/src/help/help_.rs @@ -148,7 +148,8 @@ pub fn highlight_search_in_table( let mut matches = vec![]; for record in table { - let (mut record, record_span) = if let Value::Record { val, span } = record { + let span = record.span(); + let (mut record, record_span) = if let Value::Record { val, .. } = record { (val, span) } else { return Err(ShellError::NushellFailedSpanned { @@ -165,17 +166,18 @@ pub fn highlight_search_in_table( // don't search this column return Ok(acc); } - if let Value::String { val: s, span } = val { + let span = val.span(); + if let Value::String { val: s, .. } = val { if s.to_lowercase().contains(&search_string) { - *val = Value::String { - val: highlight_search_string( + *val = Value::string( + highlight_search_string( s, orig_search_string, string_style, highlight_style, )?, - span: *span, - }; + span, + ); return Ok(true); } } diff --git a/crates/nu-command/src/help/help_aliases.rs b/crates/nu-command/src/help/help_aliases.rs index 17f9b6284..83d3a3b96 100644 --- a/crates/nu-command/src/help/help_aliases.rs +++ b/crates/nu-command/src/help/help_aliases.rs @@ -159,11 +159,7 @@ pub fn help_aliases( long_desc = nu_utils::strip_ansi_string_likely(long_desc); } - Ok(Value::String { - val: long_desc, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(long_desc, call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/help/help_commands.rs b/crates/nu-command/src/help/help_commands.rs index 482c0f9af..655bb1f48 100644 --- a/crates/nu-command/src/help/help_commands.rs +++ b/crates/nu-command/src/help/help_commands.rs @@ -109,11 +109,10 @@ pub fn help_commands( .collect::>(); if !output.is_empty() { - Ok(Value::String { - val: output.join("======================\n\n"), - span: call.head, - } - .into_pipeline_data()) + Ok( + Value::string(output.join("======================\n\n"), call.head) + .into_pipeline_data(), + ) } else { Err(ShellError::CommandNotFound(span(&[ rest[0].span, @@ -205,7 +204,7 @@ fn build_help_commands(engine_state: &EngineState, span: Span) -> Vec { )); } - Value::List { vals, span } + Value::list(vals, span) }; // Build the signature input/output table @@ -222,7 +221,7 @@ fn build_help_commands(engine_state: &EngineState, span: Span) -> Vec { )); } - Value::List { vals, span } + Value::list(vals, span) }; let record = record! { diff --git a/crates/nu-command/src/help/help_externs.rs b/crates/nu-command/src/help/help_externs.rs index 29bda80a9..4d880bea5 100644 --- a/crates/nu-command/src/help/help_externs.rs +++ b/crates/nu-command/src/help/help_externs.rs @@ -128,11 +128,10 @@ pub fn help_externs( .collect::>(); if !output.is_empty() { - Ok(Value::String { - val: output.join("======================\n\n"), - span: call.head, - } - .into_pipeline_data()) + Ok( + Value::string(output.join("======================\n\n"), call.head) + .into_pipeline_data(), + ) } else { Err(ShellError::CommandNotFound(span(&[ rest[0].span, diff --git a/crates/nu-command/src/help/help_modules.rs b/crates/nu-command/src/help/help_modules.rs index e3b8e274a..fa9985ead 100644 --- a/crates/nu-command/src/help/help_modules.rs +++ b/crates/nu-command/src/help/help_modules.rs @@ -243,11 +243,7 @@ pub fn help_modules( long_desc = nu_utils::strip_ansi_string_likely(long_desc); } - Ok(Value::String { - val: long_desc, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(long_desc, call.head).into_pipeline_data()) } } diff --git a/crates/nu-command/src/math/abs.rs b/crates/nu-command/src/math/abs.rs index 82f4a0098..14e3cc3e9 100644 --- a/crates/nu-command/src/math/abs.rs +++ b/crates/nu-command/src/math/abs.rs @@ -54,39 +54,34 @@ impl Command for SubCommand { vec![Example { description: "Compute absolute value of each number in a list of numbers", example: "[-50 -100.0 25] | math abs", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(50), Value::test_float(100.0), Value::test_int(25), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } } fn abs_helper(val: Value, head: Span) -> Value { + let span = val.span(); match val { - Value::Int { val, span } => Value::int(val.abs(), span), - Value::Float { val, span } => Value::Float { - val: val.abs(), - span, - }, - Value::Duration { val, span } => Value::Duration { - val: val.abs(), - span, - }, + Value::Int { val, .. } => Value::int(val.abs(), span), + Value::Float { val, .. } => Value::float(val.abs(), span), + Value::Duration { val, .. } => Value::duration(val.abs(), span), Value::Error { .. } => val, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/math/avg.rs b/crates/nu-command/src/math/avg.rs index dde933413..8b3889b6b 100644 --- a/crates/nu-command/src/math/avg.rs +++ b/crates/nu-command/src/math/avg.rs @@ -53,15 +53,10 @@ impl Command for SubCommand { pub fn average(values: &[Value], span: Span, head: Span) -> Result { let sum = reducer_for(Reduce::Summation); let total = &sum(Value::int(0, head), values.to_vec(), span, head)?; + let span = total.span(); match total { - Value::Filesize { val, span } => Ok(Value::Filesize { - val: val / values.len() as i64, - span: *span, - }), - Value::Duration { val, span } => Ok(Value::Duration { - val: val / values.len() as i64, - span: *span, - }), + Value::Filesize { val, .. } => Ok(Value::filesize(val / values.len() as i64, span)), + Value::Duration { val, .. } => Ok(Value::duration(val / values.len() as i64, span)), _ => total.div(head, &Value::int(values.len() as i64, head), head), } } diff --git a/crates/nu-command/src/math/ceil.rs b/crates/nu-command/src/math/ceil.rs index c6d12a5dd..d2487dddf 100644 --- a/crates/nu-command/src/math/ceil.rs +++ b/crates/nu-command/src/math/ceil.rs @@ -53,31 +53,29 @@ impl Command for SubCommand { vec![Example { description: "Apply the ceil function to a list of numbers", example: "[1.5 2.3 -3.1] | math ceil", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(-3)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(3), Value::test_int(-3)], + Span::test_data(), + )), }] } } fn operate(value: Value, head: Span) -> Value { + let span = value.span(); match value { Value::Int { .. } => value, - Value::Float { val, span } => Value::Int { - val: val.ceil() as i64, - span, - }, + Value::Float { val, .. } => Value::int(val.ceil() as i64, span), Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/math/floor.rs b/crates/nu-command/src/math/floor.rs index 416558c61..14d8d7bdb 100644 --- a/crates/nu-command/src/math/floor.rs +++ b/crates/nu-command/src/math/floor.rs @@ -53,31 +53,29 @@ impl Command for SubCommand { vec![Example { description: "Apply the floor function to a list of numbers", example: "[1.5 2.3 -3.1] | math floor", - result: Some(Value::List { - vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(-4)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(1), Value::test_int(2), Value::test_int(-4)], + Span::test_data(), + )), }] } } fn operate(value: Value, head: Span) -> Value { + let span = value.span(); match value { Value::Int { .. } => value, - Value::Float { val, span } => Value::Int { - val: val.floor() as i64, - span, - }, + Value::Float { val, .. } => Value::int(val.floor() as i64, span), Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/math/log.rs b/crates/nu-command/src/math/log.rs index a7b40a3db..e3577c9b0 100644 --- a/crates/nu-command/src/math/log.rs +++ b/crates/nu-command/src/math/log.rs @@ -78,39 +78,40 @@ impl Command for SubCommand { Example { example: "[16 8 4] | math log 2", description: "Get the log2 of a list of values", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_float(4.0), Value::test_float(3.0), Value::test_float(2.0), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } } fn operate(value: Value, head: Span, base: f64) -> Value { + let span = value.span(); match value { numeric @ (Value::Int { .. } | Value::Float { .. }) => { let (val, span) = match numeric { - Value::Int { val, span } => (val as f64, span), - Value::Float { val, span } => (val, span), + Value::Int { val, .. } => (val as f64, span), + Value::Float { val, .. } => (val, span), _ => unreachable!(), }; if val <= 0.0 { - return Value::Error { - error: Box::new(ShellError::UnsupportedInput( + return Value::error( + ShellError::UnsupportedInput( "'math log' undefined for values outside the open interval (0, Inf)." .into(), "value originates from here".into(), head, span, - )), + ), span, - }; + ); } // Specialize for better precision/performance let val = if base == 10.0 { @@ -121,18 +122,18 @@ fn operate(value: Value, head: Span, base: f64) -> Value { val.log(base) }; - Value::Float { val, span } + Value::float(val, span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/math/math_.rs b/crates/nu-command/src/math/math_.rs index 5c0f897a3..c861ab82b 100644 --- a/crates/nu-command/src/math/math_.rs +++ b/crates/nu-command/src/math/math_.rs @@ -34,16 +34,16 @@ impl Command for MathCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &MathCommand.signature(), &MathCommand.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/math/mode.rs b/crates/nu-command/src/math/mode.rs index c2ded5c80..2de4d050c 100644 --- a/crates/nu-command/src/math/mode.rs +++ b/crates/nu-command/src/math/mode.rs @@ -82,10 +82,10 @@ impl Command for SubCommand { Example { description: "Compute the mode(s) of a list of numbers", example: "[3 3 9 12 12 15] | math mode", - result: Some(Value::List { - vals: vec![Value::test_int(3), Value::test_int(12)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(3), Value::test_int(12)], + Span::test_data(), + )), }, Example { description: "Compute the mode(s) of the columns of a table", @@ -93,14 +93,11 @@ impl Command for SubCommand { result: Some(Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![ - Value::List { - vals: vec![Value::test_int(1)], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_int(-1), Value::test_int(3), Value::test_int(5)], - span: Span::test_data(), - }, + Value::list(vec![Value::test_int(1)], Span::test_data()), + Value::list( + vec![Value::test_int(-1), Value::test_int(3), Value::test_int(5)], + Span::test_data(), + ), ], })), }, @@ -176,10 +173,7 @@ pub fn mode(values: &[Value], _span: Span, head: Span) -> Result Value { @@ -187,14 +181,8 @@ fn recreate_value(hashable_value: &HashableType, head: Span) -> Value { match &hashable_value.original_type { NumberTypes::Int => Value::int(i64::from_ne_bytes(bytes), head), NumberTypes::Float => Value::float(f64::from_ne_bytes(bytes), head), - NumberTypes::Duration => Value::Duration { - val: i64::from_ne_bytes(bytes), - span: head, - }, - NumberTypes::Filesize => Value::Filesize { - val: i64::from_ne_bytes(bytes), - span: head, - }, + NumberTypes::Duration => Value::duration(i64::from_ne_bytes(bytes), head), + NumberTypes::Filesize => Value::filesize(i64::from_ne_bytes(bytes), head), } } diff --git a/crates/nu-command/src/math/reducers.rs b/crates/nu-command/src/math/reducers.rs index b7b130d2a..e87914673 100644 --- a/crates/nu-command/src/math/reducers.rs +++ b/crates/nu-command/src/math/reducers.rs @@ -86,22 +86,22 @@ pub fn sum(data: Vec, span: Span, head: Span) -> Result Ok(Value::Filesize { - val: 0, - span: *span, - }), - Some(Value::Duration { span, .. }) => Ok(Value::Duration { - val: 0, - span: *span, - }), - Some(Value::Int { span, .. }) | Some(Value::Float { span, .. }) => Ok(Value::int(0, *span)), + Some(v) => { + let span = v.span(); + match v { + Value::Filesize { .. } => Ok(Value::filesize(0, span)), + Value::Duration { .. } => Ok(Value::duration(0, span)), + Value::Int { .. } | Value::Float { .. } => Ok(Value::int(0, span)), + _ => Ok(Value::nothing(head)), + } + } + None => Err(ShellError::UnsupportedInput( "Empty input".to_string(), "value originates from here".into(), head, span, )), - _ => Ok(Value::nothing(head)), }?; for value in &data { @@ -130,14 +130,19 @@ pub fn product(data: Vec, span: Span, head: Span) -> Result Ok(Value::int(1, *span)), + Some(v) => { + let span = v.span(); + match v { + Value::Int { .. } | Value::Float { .. } => Ok(Value::int(1, span)), + _ => Ok(Value::nothing(head)), + } + } None => Err(ShellError::UnsupportedInput( "Empty input".to_string(), "value originates from here".into(), head, span, )), - _ => Ok(Value::nothing(head)), }?; for value in &data { diff --git a/crates/nu-command/src/math/round.rs b/crates/nu-command/src/math/round.rs index 3e9277ebf..8bf660054 100644 --- a/crates/nu-command/src/math/round.rs +++ b/crates/nu-command/src/math/round.rs @@ -64,34 +64,34 @@ impl Command for SubCommand { Example { description: "Apply the round function to a list of numbers", example: "[1.5 2.3 -3.1] | math round", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(2), Value::test_int(-3)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(2), Value::test_int(-3)], + Span::test_data(), + )), }, Example { description: "Apply the round function with precision specified", example: "[1.555 2.333 -3.111] | math round -p 2", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_float(1.56), Value::test_float(2.33), Value::test_float(-3.11), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Apply negative precision to a list of numbers", example: "[123, 123.3, -123.4] | math round -p -1", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_int(120), Value::test_int(120), Value::test_int(-120), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -99,37 +99,32 @@ impl Command for SubCommand { fn operate(value: Value, head: Span, precision: Option) -> Value { // We treat int values as float values in order to avoid code repetition in the match closure - let value = if let Value::Int { val, span } = value { - Value::Float { - val: val as f64, - span, - } + let span = value.span(); + let value = if let Value::Int { val, .. } = value { + Value::float(val as f64, span) } else { value }; match value { - Value::Float { val, span } => match precision { - Some(precision_number) => Value::Float { - val: ((val * ((10_f64).powf(precision_number as f64))).round() - / (10_f64).powf(precision_number as f64)), + Value::Float { val, .. } => match precision { + Some(precision_number) => Value::float( + (val * ((10_f64).powf(precision_number as f64))).round() + / (10_f64).powf(precision_number as f64), span, - }, - None => Value::Int { - val: val.round() as i64, - span, - }, + ), + None => Value::int(val.round() as i64, span), }, Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/math/sqrt.rs b/crates/nu-command/src/math/sqrt.rs index baf34c45e..446b91692 100644 --- a/crates/nu-command/src/math/sqrt.rs +++ b/crates/nu-command/src/math/sqrt.rs @@ -53,53 +53,54 @@ impl Command for SubCommand { vec![Example { description: "Compute the square root of each number in a list", example: "[9 16] | math sqrt", - result: Some(Value::List { - vals: vec![Value::test_int(3), Value::test_int(4)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(3), Value::test_int(4)], + Span::test_data(), + )), }] } } fn operate(value: Value, head: Span) -> Value { + let span = value.span(); match value { - Value::Int { val, span } => { + Value::Int { val, .. } => { let squared = (val as f64).sqrt(); if squared.is_nan() { return error_negative_sqrt(head, span); } - Value::Float { val: squared, span } + Value::float(squared, span) } - Value::Float { val, span } => { + Value::Float { val, .. } => { let squared = val.sqrt(); if squared.is_nan() { return error_negative_sqrt(head, span); } - Value::Float { val: squared, span } + Value::float(squared, span) } Value::Error { .. } => value, - other => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + other => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "numeric".into(), wrong_type: other.get_type().to_string(), dst_span: head, src_span: other.span(), - }), - span: head, - }, + }, + head, + ), } } fn error_negative_sqrt(head: Span, span: Span) -> Value { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Value::error( + ShellError::UnsupportedInput( String::from("Can't square root a negative number"), "value originates from here".into(), head, span, - )), + ), span, - } + ) } #[cfg(test)] diff --git a/crates/nu-command/src/math/stddev.rs b/crates/nu-command/src/math/stddev.rs index 66f25914c..623582ed0 100644 --- a/crates/nu-command/src/math/stddev.rs +++ b/crates/nu-command/src/math/stddev.rs @@ -67,19 +67,13 @@ impl Command for SubCommand { pub fn compute_stddev(sample: bool) -> impl Fn(&[Value], Span, Span) -> Result { move |values: &[Value], span: Span, head: Span| { - let variance = variance(sample)(values, span, head); + // variance() produces its own usable error, so we can use `?` to propagated the error. + let variance = variance(sample)(values, span, head)?; + let val_span = variance.span(); match variance { - Ok(Value::Float { val, span }) => Ok(Value::Float { - val: val.sqrt(), - span, - }), - Ok(Value::Int { val, span }) => Ok(Value::Float { - val: (val as f64).sqrt(), - span, - }), - // variance() produces its own usable error, which can simply be propagated. - Err(e) => Err(e), - other => other, + Value::Float { val, .. } => Ok(Value::float(val.sqrt(), val_span)), + Value::Int { val, .. } => Ok(Value::float((val as f64).sqrt(), val_span)), + other => Ok(other), } } } diff --git a/crates/nu-command/src/math/utils.rs b/crates/nu-command/src/math/utils.rs index bed730d21..9149183bd 100644 --- a/crates/nu-command/src/math/utils.rs +++ b/crates/nu-command/src/math/utils.rs @@ -71,7 +71,7 @@ pub fn calculate( PipelineData::ListStream(s, ..) => { helper_for_tables(&s.collect::>(), span, name, mf) } - PipelineData::Value(Value::List { ref vals, span }, ..) => match &vals[..] { + PipelineData::Value(Value::List { ref vals, .. }, ..) => match &vals[..] { [Value::Record { .. }, _end @ ..] => helper_for_tables( vals, values.span().expect("PipelineData::Value had no span"), @@ -80,7 +80,7 @@ pub fn calculate( ), _ => mf(vals, span, name), }, - PipelineData::Value(Value::Record { val: record, span }, ..) => { + PipelineData::Value(Value::Record { val: record, .. }, ..) => { let new_vals: Result, ShellError> = record .vals .into_iter() @@ -97,7 +97,7 @@ pub fn calculate( Err(err) => Err(err), } } - PipelineData::Value(Value::Range { val, span, .. }, ..) => { + PipelineData::Value(Value::Range { val, .. }, ..) => { let new_vals: Result, ShellError> = val .into_range_iter(None)? .map(|val| mf(&[val], span, name)) diff --git a/crates/nu-command/src/network/http/http_.rs b/crates/nu-command/src/network/http/http_.rs index 81493437f..dc4fced11 100644 --- a/crates/nu-command/src/network/http/http_.rs +++ b/crates/nu-command/src/network/http/http_.rs @@ -40,16 +40,16 @@ impl Command for Http { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Http.signature(), &Http.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/network/url/build_query.rs b/crates/nu-command/src/network/url/build_query.rs index 3c397c36e..386d34e36 100644 --- a/crates/nu-command/src/network/url/build_query.rs +++ b/crates/nu-command/src/network/url/build_query.rs @@ -64,43 +64,46 @@ impl Command for SubCommand { fn to_url(input: PipelineData, head: Span) -> Result { let output: Result = input .into_iter() - .map(move |value| match value { - Value::Record { ref val, span } => { - let mut row_vec = vec![]; - for (k, v) in val { - match v.as_string() { - Ok(s) => { - row_vec.push((k.clone(), s.to_string())); - } - _ => { - return Err(ShellError::UnsupportedInput( - "Expected a record with string values".to_string(), - "value originates from here".into(), - head, - span, - )); + .map(move |value| { + let span = value.span(); + match value { + Value::Record { ref val, .. } => { + let mut row_vec = vec![]; + for (k, v) in val { + match v.as_string() { + Ok(s) => { + row_vec.push((k.clone(), s.to_string())); + } + _ => { + return Err(ShellError::UnsupportedInput( + "Expected a record with string values".to_string(), + "value originates from here".into(), + head, + span, + )); + } } } - } - match serde_urlencoded::to_string(row_vec) { - Ok(s) => Ok(s), - _ => Err(ShellError::CantConvert { - to_type: "URL".into(), - from_type: value.get_type().to_string(), - span: head, - help: None, - }), + match serde_urlencoded::to_string(row_vec) { + Ok(s) => Ok(s), + _ => Err(ShellError::CantConvert { + to_type: "URL".into(), + from_type: value.get_type().to_string(), + span: head, + help: None, + }), + } } + // Propagate existing errors + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::UnsupportedInput( + "Expected a table from pipeline".to_string(), + "value originates from here".into(), + head, + other.span(), + )), } - // Propagate existing errors - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::UnsupportedInput( - "Expected a table from pipeline".to_string(), - "value originates from here".into(), - head, - other.span(), - )), }) .collect(); diff --git a/crates/nu-command/src/network/url/encode.rs b/crates/nu-command/src/network/url/encode.rs index 60b7d31a5..f8c7d9b09 100644 --- a/crates/nu-command/src/network/url/encode.rs +++ b/crates/nu-command/src/network/url/encode.rs @@ -76,14 +76,14 @@ impl Command for SubCommand { Example { description: "Encode multiple urls with escape characters in list", example: "['https://example.com/foo bar' 'https://example.com/a>b' '中文字/eng/12 34'] | url encode", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("https://example.com/foo%20bar"), Value::test_string("https://example.com/a%3Eb"), Value::test_string("%E4%B8%AD%E6%96%87%E5%AD%97/eng/12%2034"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Encode all non alphanumeric chars with all flag", @@ -98,21 +98,18 @@ fn action_all(input: &Value, _arg: &CellPathOnlyArgs, head: Span) -> Value { match input { Value::String { val, .. } => { const FRAGMENT: &AsciiSet = NON_ALPHANUMERIC; - Value::String { - val: utf8_percent_encode(val, FRAGMENT).to_string(), - span: head, - } + Value::string(utf8_percent_encode(val, FRAGMENT).to_string(), head) } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } @@ -120,21 +117,18 @@ fn action(input: &Value, _arg: &CellPathOnlyArgs, head: Span) -> Value { match input { Value::String { val, .. } => { const FRAGMENT: &AsciiSet = &NON_ALPHANUMERIC.remove(b'/').remove(b':').remove(b'.'); - Value::String { - val: utf8_percent_encode(val, FRAGMENT).to_string(), - span: head, - } + Value::string(utf8_percent_encode(val, FRAGMENT).to_string(), head) } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/network/url/join.rs b/crates/nu-command/src/network/url/join.rs index f36613af3..aa6c814c5 100644 --- a/crates/nu-command/src/network/url/join.rs +++ b/crates/nu-command/src/network/url/join.rs @@ -91,23 +91,26 @@ impl Command for SubCommand { let output: Result = input .into_iter() - .map(move |value| match value { - Value::Record { val, span } => { - let url_components = val - .into_iter() - .try_fold(UrlComponents::new(), |url, (k, v)| { - url.add_component(k, v, span) - }); + .map(move |value| { + let span = value.span(); + match value { + Value::Record { val, .. } => { + let url_components = val + .into_iter() + .try_fold(UrlComponents::new(), |url, (k, v)| { + url.add_component(k, v, span) + }); - url_components?.to_url(span) + url_components?.to_url(span) + } + Value::Error { error, .. } => Err(*error), + other => Err(ShellError::UnsupportedInput( + "Expected a record from pipeline".to_string(), + "value originates from here".into(), + head, + other.span(), + )), } - Value::Error { error, .. } => Err(*error), - other => Err(ShellError::UnsupportedInput( - "Expected a record from pipeline".to_string(), - "value originates from here".into(), - head, - other.span(), - )), }) .collect(); @@ -135,9 +138,10 @@ impl UrlComponents { } pub fn add_component(self, key: String, value: Value, _span: Span) -> Result { + let span = value.span(); if key == "port" { return match value { - Value::String { val, span } => { + Value::String { val, .. } => { if val.trim().is_empty() { Ok(self) } else { @@ -155,7 +159,7 @@ impl UrlComponents { } } } - Value::Int { val, span: _ } => Ok(Self { + Value::Int { val, .. } => Ok(Self { port: Some(val), ..self }), @@ -171,7 +175,7 @@ impl UrlComponents { if key == "params" { return match value { - Value::Record { ref val, span } => { + Value::Record { ref val, .. } => { let mut qs = val .iter() .map(|(k, v)| match v.as_string() { diff --git a/crates/nu-command/src/network/url/url_.rs b/crates/nu-command/src/network/url/url_.rs index cc94b0746..078588913 100644 --- a/crates/nu-command/src/network/url/url_.rs +++ b/crates/nu-command/src/network/url/url_.rs @@ -38,16 +38,16 @@ impl Command for Url { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Url.signature(), &Url.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/path/exists.rs b/crates/nu-command/src/path/exists.rs index 694ce4efc..0b2acf9e7 100644 --- a/crates/nu-command/src/path/exists.rs +++ b/crates/nu-command/src/path/exists.rs @@ -131,18 +131,15 @@ If you need to distinguish dirs and files, please use `path type`."# fn exists(path: &Path, span: Span, args: &Arguments) -> Value { let path = expand_path_with(path, &args.pwd); - Value::Bool { - val: match path.try_exists() { + Value::bool( + match path.try_exists() { Ok(exists) => exists, Err(err) => { - return Value::Error { - error: Box::new(ShellError::IOErrorSpanned(err.to_string(), span)), - span, - } + return Value::error(ShellError::IOErrorSpanned(err.to_string(), span), span) } }, span, - } + ) } #[cfg(test)] diff --git a/crates/nu-command/src/path/expand.rs b/crates/nu-command/src/path/expand.rs index bf58b6990..a759b4b9b 100644 --- a/crates/nu-command/src/path/expand.rs +++ b/crates/nu-command/src/path/expand.rs @@ -156,8 +156,8 @@ fn expand(path: &Path, span: Span, args: &Arguments) -> Value { Value::string(p.to_string_lossy(), span) } } - Err(_) => Value::Error { - error: Box::new(ShellError::GenericError( + Err(_) => Value::error( + ShellError::GenericError( "Could not expand path".into(), "could not be expanded (path might not exist, non-final \ component is not a directory, or other cause)" @@ -165,9 +165,9 @@ fn expand(path: &Path, span: Span, args: &Arguments) -> Value { Some(span), None, Vec::new(), - )), + ), span, - }, + ), } } else if args.not_follow_symlink { Value::string(expand_path_with(path, &args.cwd).to_string_lossy(), span) diff --git a/crates/nu-command/src/path/join.rs b/crates/nu-command/src/path/join.rs index 13e9285e8..189fd7332 100644 --- a/crates/nu-command/src/path/join.rs +++ b/crates/nu-command/src/path/join.rs @@ -103,10 +103,10 @@ the output of 'path parse' and 'path split' subcommands."# Example { description: "Join a table of structured paths into a list of paths", example: r"[ [parent stem extension]; ['C:\Users\viking' 'spam' 'txt']] | path join", - result: Some(Value::List { - vals: vec![Value::test_string(r"C:\Users\viking\spam.txt")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string(r"C:\Users\viking\spam.txt")], + Span::test_data(), + )), }, ] } @@ -137,10 +137,10 @@ the output of 'path parse' and 'path split' subcommands."# Example { description: "Join a table of structured paths into a list of paths", example: r"[[ parent stem extension ]; [ '/home/viking' 'spam' 'txt' ]] | path join", - result: Some(Value::List { - vals: vec![Value::test_string(r"/home/viking/spam.txt")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string(r"/home/viking/spam.txt")], + Span::test_data(), + )), }, ] } @@ -168,10 +168,11 @@ fn run(call: &Call, args: &Arguments, input: PipelineData) -> Result Value { + let span = v.span(); match v { Value::String { ref val, .. } => join_single(Path::new(val), head, args), - Value::Record { val, span } => join_record(&val, head, span, args), - Value::List { vals, span } => join_list(&vals, head, span, args), + Value::Record { val, .. } => join_record(&val, head, span, args), + Value::List { vals, .. } => join_list(&vals, head, span, args), _ => super::handle_invalid_values(v, head), } @@ -200,16 +201,16 @@ fn join_list(parts: &[Value], head: Span, span: Span, args: &Arguments) -> Value .map(|r| join_record(r, head, span, args)) .collect(); - Value::List { vals, span } + Value::list(vals, span) } - Err(_) => Value::Error { - error: Box::new(ShellError::PipelineMismatch { + Err(_) => Value::error( + ShellError::PipelineMismatch { exp_input_type: "string or record".into(), dst_span: head, src_span: span, - }), + }, span, - }, + ), } } } @@ -218,10 +219,7 @@ fn join_list(parts: &[Value], head: Span, span: Span, args: &Arguments) -> Value fn join_record(record: &Record, head: Span, span: Span, args: &Arguments) -> Value { match merge_record(record, head, span) { Ok(p) => join_single(p.as_path(), head, args), - Err(error) => Value::Error { - error: Box::new(error), - span, - }, + Err(error) => Value::error(error, span), } } diff --git a/crates/nu-command/src/path/mod.rs b/crates/nu-command/src/path/mod.rs index d1fc709a3..893f64475 100644 --- a/crates/nu-command/src/path/mod.rs +++ b/crates/nu-command/src/path/mod.rs @@ -36,17 +36,15 @@ where F: Fn(&StdPath, Span, &A) -> Value + Send + Sync + 'static, A: PathSubcommandArguments + Send + Sync + 'static, { + let span = v.span(); match v { - Value::String { val, span } => cmd(StdPath::new(&val), span, args), + Value::String { val, .. } => cmd(StdPath::new(&val), span, args), _ => handle_invalid_values(v, name), } } fn handle_invalid_values(rest: Value, name: Span) -> Value { - Value::Error { - error: Box::new(err_from_value(&rest, name)), - span: name, - } + Value::error(err_from_value(&rest, name), name) } fn err_from_value(rest: &Value, name: Span) -> ShellError { diff --git a/crates/nu-command/src/path/path_.rs b/crates/nu-command/src/path/path_.rs index 4c1a2dc52..5ce036b81 100644 --- a/crates/nu-command/src/path/path_.rs +++ b/crates/nu-command/src/path/path_.rs @@ -47,16 +47,16 @@ the path literal."# call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &PathCommand.signature(), &PathCommand.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/path/relative_to.rs b/crates/nu-command/src/path/relative_to.rs index ac6bffaf8..eed19eedb 100644 --- a/crates/nu-command/src/path/relative_to.rs +++ b/crates/nu-command/src/path/relative_to.rs @@ -153,15 +153,15 @@ fn relative_to(path: &Path, span: Span, args: &Arguments) -> Value { let rhs = expand_to_real_path(&args.path.item); match lhs.strip_prefix(&rhs) { Ok(p) => Value::string(p.to_string_lossy(), span), - Err(e) => Value::Error { - error: Box::new(ShellError::CantConvert { + Err(e) => Value::error( + ShellError::CantConvert { to_type: e.to_string(), from_type: "string".into(), span, help: None, - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/path/split.rs b/crates/nu-command/src/path/split.rs index 349b80b02..1c67f69f4 100644 --- a/crates/nu-command/src/path/split.rs +++ b/crates/nu-command/src/path/split.rs @@ -85,21 +85,21 @@ impl Command for SubCommand { Example { description: "Split a path into parts", example: r"'C:\Users\viking\spam.txt' | path split", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string(r"C:\"), Value::test_string("Users"), Value::test_string("viking"), Value::test_string("spam.txt"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split paths in list into parts", example: r"[ C:\Users\viking\spam.txt C:\Users\viking\eggs.txt ] | path split", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_list(vec![ Value::test_string(r"C:\"), Value::test_string("Users"), @@ -113,8 +113,8 @@ impl Command for SubCommand { Value::test_string("eggs.txt"), ]), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -125,21 +125,21 @@ impl Command for SubCommand { Example { description: "Split a path into parts", example: r"'/home/viking/spam.txt' | path split", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("/"), Value::test_string("home"), Value::test_string("viking"), Value::test_string("spam.txt"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split paths in list into parts", example: r"[ /home/viking/spam.txt /home/viking/eggs.txt ] | path split", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_list(vec![ Value::test_string("/"), Value::test_string("home"), @@ -153,24 +153,23 @@ impl Command for SubCommand { Value::test_string("eggs.txt"), ]), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } } fn split(path: &Path, span: Span, _: &Arguments) -> Value { - Value::List { - vals: path - .components() + Value::list( + path.components() .filter_map(|comp| { let comp = process_component(comp); comp.map(|s| Value::string(s, span)) }) .collect(), span, - } + ) } #[cfg(windows)] diff --git a/crates/nu-command/src/platform/ansi/ansi_.rs b/crates/nu-command/src/platform/ansi/ansi_.rs index 381fcea1e..b17ac329d 100644 --- a/crates/nu-command/src/platform/ansi/ansi_.rs +++ b/crates/nu-command/src/platform/ansi/ansi_.rs @@ -673,7 +673,7 @@ Operating system commands: } }; - let param_is_string = matches!(code, Value::String { val: _, span: _ }); + let param_is_string = matches!(code, Value::String { .. }); if escape && osc { return Err(ShellError::IncompatibleParameters { diff --git a/crates/nu-command/src/platform/ansi/strip.rs b/crates/nu-command/src/platform/ansi/strip.rs index 410656c96..c6f24ce32 100644 --- a/crates/nu-command/src/platform/ansi/strip.rs +++ b/crates/nu-command/src/platform/ansi/strip.rs @@ -56,20 +56,21 @@ impl Command for SubCommand { } fn action(input: &Value, _args: &CellPathOnlyArgs, _span: Span) -> Value { + let span = input.span(); match input { - Value::String { val, span } => { - Value::string(nu_utils::strip_ansi_likely(val).to_string(), *span) + Value::String { val, .. } => { + Value::string(nu_utils::strip_ansi_likely(val).to_string(), span) } other => { let got = format!("value is {}, not string", other.get_type()); - Value::Error { - error: Box::new(ShellError::TypeMismatch { + Value::error( + ShellError::TypeMismatch { err_message: got, span: other.span(), - }), - span: other.span(), - } + }, + other.span(), + ) } } } diff --git a/crates/nu-command/src/platform/clear.rs b/crates/nu-command/src/platform/clear.rs index 5f3eab958..ad33de0ca 100644 --- a/crates/nu-command/src/platform/clear.rs +++ b/crates/nu-command/src/platform/clear.rs @@ -49,7 +49,7 @@ impl Command for Clear { .map_err(|e| ShellError::IOErrorSpanned(e.to_string(), span))?; } - Ok(Value::Nothing { span }.into_pipeline_data()) + Ok(Value::nothing(span).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/platform/dir_info.rs b/crates/nu-command/src/platform/dir_info.rs index c9c0d6cd5..3baa7138f 100644 --- a/crates/nu-command/src/platform/dir_info.rs +++ b/crates/nu-command/src/platform/dir_info.rs @@ -238,9 +238,6 @@ where Value::nothing(tag) } else { let values = vec.into_iter().map(Into::into).collect::>(); - Value::List { - vals: values, - span: tag, - } + Value::list(values, tag) } } diff --git a/crates/nu-command/src/platform/du.rs b/crates/nu-command/src/platform/du.rs index 3fbc5e599..36b71cbe9 100644 --- a/crates/nu-command/src/platform/du.rs +++ b/crates/nu-command/src/platform/du.rs @@ -179,10 +179,7 @@ impl Command for Du { } } Err(e) => { - output.push(Value::Error { - error: Box::new(e), - span: tag, - }); + output.push(Value::error(e, tag)); } } } diff --git a/crates/nu-command/src/platform/input/input_.rs b/crates/nu-command/src/platform/input/input_.rs index 8a8ef50ef..54e6f575c 100644 --- a/crates/nu-command/src/platform/input/input_.rs +++ b/crates/nu-command/src/platform/input/input_.rs @@ -168,11 +168,7 @@ impl Command for Input { if !suppress_output { std::io::stdout().write_all(b"\n")?; } - Ok(Value::String { - val: buf, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(buf, call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/platform/input/input_listen.rs b/crates/nu-command/src/platform/input/input_listen.rs index 0dfcd0bf4..e974a6f0f 100644 --- a/crates/nu-command/src/platform/input/input_listen.rs +++ b/crates/nu-command/src/platform/input/input_listen.rs @@ -151,7 +151,8 @@ impl EventTypeFilter { if let Value::List { vals, .. } = value { let mut filter = Self::none(); for event_type in vals { - if let Value::String { val, span } = event_type { + let span = event_type.span(); + if let Value::String { val, .. } = event_type { match val.as_str() { "focus" => filter.listen_focus = true, "key" => filter.listen_key = true, diff --git a/crates/nu-command/src/platform/input/list.rs b/crates/nu-command/src/platform/input/list.rs index ea206a4a1..8d7f4fdf9 100644 --- a/crates/nu-command/src/platform/input/list.rs +++ b/crates/nu-command/src/platform/input/list.rs @@ -231,21 +231,15 @@ impl Command for InputList { Ok(match ans { InteractMode::Multi(res) => match res { - Some(opts) => Value::List { - vals: opts.iter().map(|s| options[*s].value.clone()).collect(), - span: head, - }, - None => Value::List { - vals: vec![], - span: head, - }, + Some(opts) => Value::list( + opts.iter().map(|s| options[*s].value.clone()).collect(), + head, + ), + None => Value::list(vec![], head), }, InteractMode::Single(res) => match res { Some(opt) => options[opt].value.clone(), - None => Value::String { - val: "".to_string(), - span: head, - }, + None => Value::string("".to_string(), head), }, } .into_pipeline_data()) diff --git a/crates/nu-command/src/platform/kill.rs b/crates/nu-command/src/platform/kill.rs index 994de9619..8d1f211db 100644 --- a/crates/nu-command/src/platform/kill.rs +++ b/crates/nu-command/src/platform/kill.rs @@ -172,14 +172,11 @@ impl Command for Kill { .trim_end(), ); if val.is_empty() { - Ok(Value::Nothing { span: call.head }.into_pipeline_data()) + Ok(Value::nothing(call.head).into_pipeline_data()) } else { - Ok(vec![Value::String { - val, - span: call.head, - }] - .into_iter() - .into_pipeline_data(engine_state.ctrlc.clone())) + Ok(vec![Value::string(val, call.head)] + .into_iter() + .into_pipeline_data(engine_state.ctrlc.clone())) } } diff --git a/crates/nu-command/src/platform/sleep.rs b/crates/nu-command/src/platform/sleep.rs index 0c2624cde..2877fc1bf 100644 --- a/crates/nu-command/src/platform/sleep.rs +++ b/crates/nu-command/src/platform/sleep.rs @@ -66,7 +66,7 @@ impl Command for Sleep { } } - Ok(Value::Nothing { span: call.head }.into_pipeline_data()) + Ok(Value::nothing(call.head).into_pipeline_data()) } fn examples(&self) -> Vec { @@ -74,9 +74,7 @@ impl Command for Sleep { Example { description: "Sleep for 1sec", example: "sleep 1sec", - result: Some(Value::Nothing { - span: Span::test_data(), - }), + result: Some(Value::nothing(Span::test_data())), }, Example { description: "Sleep for 3sec", diff --git a/crates/nu-command/src/random/bool.rs b/crates/nu-command/src/random/bool.rs index e686fbee6..ddcb2c8dc 100644 --- a/crates/nu-command/src/random/bool.rs +++ b/crates/nu-command/src/random/bool.rs @@ -84,13 +84,7 @@ fn bool( let mut rng = thread_rng(); let bool_result: bool = rng.gen_bool(probability); - Ok(PipelineData::Value( - Value::Bool { - val: bool_result, - span, - }, - None, - )) + Ok(PipelineData::Value(Value::bool(bool_result, span), None)) } #[cfg(test)] diff --git a/crates/nu-command/src/random/chars.rs b/crates/nu-command/src/random/chars.rs index 23a29aafe..bb1a641c2 100644 --- a/crates/nu-command/src/random/chars.rs +++ b/crates/nu-command/src/random/chars.rs @@ -79,10 +79,7 @@ fn chars( .collect::(); Ok(PipelineData::Value( - Value::String { - val: random_string, - span, - }, + Value::string(random_string, span), None, )) } diff --git a/crates/nu-command/src/random/decimal.rs b/crates/nu-command/src/random/decimal.rs index 6fc596901..fd11f8c70 100644 --- a/crates/nu-command/src/random/decimal.rs +++ b/crates/nu-command/src/random/decimal.rs @@ -94,10 +94,7 @@ fn decimal( span, }), Some(Ordering::Equal) => Ok(PipelineData::Value( - Value::Float { - val: min, - span: Span::new(64, 64), - }, + Value::float(min, Span::new(64, 64)), None, )), _ => { @@ -105,10 +102,7 @@ fn decimal( let result: f64 = thread_rng.gen_range(min..max); Ok(PipelineData::Value( - Value::Float { - val: result, - span: Span::new(64, 64), - }, + Value::float(result, Span::new(64, 64)), None, )) } diff --git a/crates/nu-command/src/random/dice.rs b/crates/nu-command/src/random/dice.rs index f885e390f..fd1603126 100644 --- a/crates/nu-command/src/random/dice.rs +++ b/crates/nu-command/src/random/dice.rs @@ -79,10 +79,7 @@ fn dice( let iter = (0..dice).map(move |_| { let mut thread_rng = thread_rng(); - Value::Int { - val: thread_rng.gen_range(1..sides + 1) as i64, - span, - } + Value::int(thread_rng.gen_range(1..sides + 1) as i64, span) }); Ok(PipelineData::ListStream( diff --git a/crates/nu-command/src/random/integer.rs b/crates/nu-command/src/random/integer.rs index b3365a0cf..ed44e7cf2 100644 --- a/crates/nu-command/src/random/integer.rs +++ b/crates/nu-command/src/random/integer.rs @@ -93,12 +93,12 @@ fn integer( right_flank: max.to_string(), span, }), - Some(Ordering::Equal) => Ok(PipelineData::Value(Value::Int { val: min, span }, None)), + Some(Ordering::Equal) => Ok(PipelineData::Value(Value::int(min, span), None)), _ => { let mut thread_rng = thread_rng(); let result: i64 = thread_rng.gen_range(min..=max); - Ok(PipelineData::Value(Value::Int { val: result, span }, None)) + Ok(PipelineData::Value(Value::int(result, span), None)) } } } diff --git a/crates/nu-command/src/random/random_.rs b/crates/nu-command/src/random/random_.rs index b24c2ba28..3fe0a9cd7 100644 --- a/crates/nu-command/src/random/random_.rs +++ b/crates/nu-command/src/random/random_.rs @@ -38,16 +38,16 @@ impl Command for RandomCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &RandomCommand.signature(), &RandomCommand.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/random/uuid.rs b/crates/nu-command/src/random/uuid.rs index 4cff36dd9..b9186342a 100644 --- a/crates/nu-command/src/random/uuid.rs +++ b/crates/nu-command/src/random/uuid.rs @@ -49,10 +49,7 @@ fn uuid(call: &Call) -> Result { let span = call.head; let uuid_4 = Uuid::new_v4().hyphenated().to_string(); - Ok(PipelineData::Value( - Value::String { val: uuid_4, span }, - None, - )) + Ok(PipelineData::Value(Value::string(uuid_4, span), None)) } #[cfg(test)] diff --git a/crates/nu-command/src/sort_utils.rs b/crates/nu-command/src/sort_utils.rs index a5121c187..2f7874e44 100644 --- a/crates/nu-command/src/sort_utils.rs +++ b/crates/nu-command/src/sort_utils.rs @@ -17,19 +17,20 @@ pub fn sort_value( insensitive: bool, natural: bool, ) -> Result { + let span = val.span(); match val { - Value::List { vals, span } => { + Value::List { vals, .. } => { let mut vals = vals.clone(); - sort(&mut vals, sort_columns, *span, insensitive, natural)?; + sort(&mut vals, sort_columns, span, insensitive, natural)?; if !ascending { vals.reverse(); } - Ok(Value::List { vals, span: *span }) + Ok(Value::list(vals, span)) } - Value::CustomValue { val, span } => { - let base_val = val.to_base_value(*span)?; + Value::CustomValue { val, .. } => { + let base_val = val.to_base_value(span)?; sort_value(&base_val, sort_columns, ascending, insensitive, natural) } _ => Ok(val.to_owned()), @@ -45,8 +46,9 @@ pub fn sort_value_in_place( insensitive: bool, natural: bool, ) -> Result<(), ShellError> { - if let Value::List { vals, span } = val { - sort(vals, sort_columns, *span, insensitive, natural)?; + let span = val.span(); + if let Value::List { vals, .. } = val { + sort(vals, sort_columns, span, insensitive, natural)?; if !ascending { vals.reverse(); } @@ -61,11 +63,9 @@ pub fn sort( insensitive: bool, natural: bool, ) -> Result<(), ShellError> { + let val_span = vec.first().map(|v| v.span()).unwrap_or(span); match vec.first() { - Some(Value::Record { - val: record, - span: val_span, - }) => { + Some(Value::Record { val: record, .. }) => { if sort_columns.is_empty() { // This uses the same format as the 'requires a column name' error in split_by.rs return Err(ShellError::GenericError( @@ -82,7 +82,7 @@ pub fn sort( return Err(ShellError::CantFindColumn { col_name: nonexistent, span, - src_span: *val_span, + src_span: val_span, }); } @@ -124,19 +124,19 @@ pub fn sort( _ => { vec.sort_by(|a, b| { if insensitive { + let span_a = a.span(); + let span_b = b.span(); let lowercase_left = match a { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span: *span, - }, + Value::String { val, .. } => { + Value::string(val.to_ascii_lowercase(), span_a) + } _ => a.clone(), }; let lowercase_right = match b { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span: *span, - }, + Value::String { val, .. } => { + Value::string(val.to_ascii_lowercase(), span_b) + } _ => b.clone(), }; @@ -177,30 +177,26 @@ pub fn compare( let left_res = match left_value { Some(left_res) => left_res, - None => Value::Nothing { span }, + None => Value::nothing(span), }; let right_value = right.get_data_by_key(column); let right_res = match right_value { Some(right_res) => right_res, - None => Value::Nothing { span }, + None => Value::nothing(span), }; let result = if insensitive { + let span_left = left_res.span(); + let span_right = right_res.span(); let lowercase_left = match left_res { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span, - }, + Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), span_left), _ => left_res, }; let lowercase_right = match right_res { - Value::String { val, span } => Value::String { - val: val.to_ascii_lowercase(), - span, - }, + Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), span_right), _ => right_res, }; if natural { @@ -236,8 +232,8 @@ mod tests { #[test] fn test_sort_value() { - let val = Value::List { - vals: vec![ + let val = Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("pear"), Value::test_int(3)], @@ -251,15 +247,15 @@ mod tests { vals: vec![Value::test_string("apple"), Value::test_int(9)], }), ], - span: Span::test_data(), - }; + Span::test_data(), + ); let sorted_alphabetically = sort_value(&val, vec!["fruit".to_string()], true, false, false).unwrap(); assert_eq!( sorted_alphabetically, - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("apple"), Value::test_int(9)], @@ -273,16 +269,16 @@ mod tests { vals: vec![Value::test_string("pear"), Value::test_int(3)], }), ], - span: Span::test_data(), - } + Span::test_data(), + ) ); let sorted_by_count_desc = sort_value(&val, vec!["count".to_string()], false, false, false).unwrap(); assert_eq!( sorted_by_count_desc, - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("apple"), Value::test_int(9)], @@ -296,15 +292,15 @@ mod tests { vals: vec![Value::test_string("pear"), Value::test_int(3)], }), ], - span: Span::test_data(), - } + Span::test_data(), + ) ); } #[test] fn test_sort_value_in_place() { - let mut val = Value::List { - vals: vec![ + let mut val = Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("pear"), Value::test_int(3)], @@ -318,14 +314,14 @@ mod tests { vals: vec![Value::test_string("apple"), Value::test_int(9)], }), ], - span: Span::test_data(), - }; + Span::test_data(), + ); sort_value_in_place(&mut val, vec!["fruit".to_string()], true, false, false).unwrap(); assert_eq!( val, - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("apple"), Value::test_int(9)], @@ -339,15 +335,15 @@ mod tests { vals: vec![Value::test_string("pear"), Value::test_int(3)], }), ], - span: Span::test_data(), - } + Span::test_data(), + ) ); sort_value_in_place(&mut val, vec!["count".to_string()], false, false, false).unwrap(); assert_eq!( val, - Value::List { - vals: vec![ + Value::list( + vec![ Value::test_record(Record { cols: vec!["fruit".to_string(), "count".to_string()], vals: vec![Value::test_string("apple"), Value::test_int(9)], @@ -361,8 +357,8 @@ mod tests { vals: vec![Value::test_string("pear"), Value::test_int(3)], }), ], - span: Span::test_data(), - } + Span::test_data(), + ) ); } } diff --git a/crates/nu-command/src/strings/detect_columns.rs b/crates/nu-command/src/strings/detect_columns.rs index 95e043efa..7c520e81e 100644 --- a/crates/nu-command/src/strings/detect_columns.rs +++ b/crates/nu-command/src/strings/detect_columns.rs @@ -63,8 +63,8 @@ impl Command for DetectColumns { Example { description: "Splits string across multiple columns", example: "'a b c' | detect columns -n", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec![ "column0".to_string(), "column1".to_string(), @@ -77,7 +77,7 @@ impl Command for DetectColumns { ], })], span, - }), + )), }, Example { description: "", @@ -150,10 +150,7 @@ fn detect_columns( if headers.len() == row.len() { for (header, val) in headers.iter().zip(row.iter()) { cols.push(header.item.clone()); - vals.push(Value::String { - val: val.item.clone(), - span: name_span, - }); + vals.push(Value::string(val.item.clone(), name_span)); } } else { let mut pre_output = vec![]; @@ -217,10 +214,7 @@ fn detect_columns( } Err(processing_error) => { let err = processing_error("could not find range index", name_span); - return Value::Error { - error: Box::new(err), - span: name_span, - }; + return Value::error(err, name_span); } } } else { diff --git a/crates/nu-command/src/strings/encode_decode/base64.rs b/crates/nu-command/src/strings/encode_decode/base64.rs index 573d4679c..f44d5f9ed 100644 --- a/crates/nu-command/src/strings/encode_decode/base64.rs +++ b/crates/nu-command/src/strings/encode_decode/base64.rs @@ -90,8 +90,8 @@ fn action( "binhex" => GeneralPurpose::new(&alphabet::BIN_HEX, NO_PAD), "crypt" => GeneralPurpose::new(&alphabet::CRYPT, NO_PAD), "mutf7" => GeneralPurpose::new(&alphabet::IMAP_MUTF7, NO_PAD), - not_valid => return Value::Error { error: - Box::new(ShellError::GenericError( + not_valid => return Value::error ( + ShellError::GenericError( "value is not an accepted character set".to_string(), format!( "{not_valid} is not a valid character-set.\nPlease use `help encode base64` to see a list of valid character sets." @@ -99,48 +99,46 @@ fn action( Some(config_character_set.span), None, Vec::new(), - )), span:config_character_set.span} + ), config_character_set.span) }; + let value_span = input.span(); match input { // Propagate existing errors. Value::Error { .. } => input.clone(), - Value::Binary { val, span } => match base64_config.action_type { + Value::Binary { val, .. } => match base64_config.action_type { ActionType::Encode => { let mut enc_vec = Vec::new(); enc_vec.resize(val.len() * 4 / 3 + 4, 0); let bytes_written = match base64_engine.encode_slice(val, &mut enc_vec) { Ok(bytes_written) => bytes_written, Err(err) => { - return Value::Error { - error: Box::new(ShellError::GenericError( + return Value::error( + ShellError::GenericError( "Error encoding data".into(), err.to_string(), - Some(*span), + Some(value_span), None, Vec::new(), - )), - span: *span, - } + ), + value_span, + ) } }; enc_vec.truncate(bytes_written); Value::string(std::str::from_utf8(&enc_vec).unwrap_or(""), command_span) } - ActionType::Decode => Value::Error { - error: Box::new(ShellError::UnsupportedInput( + ActionType::Decode => Value::error( + ShellError::UnsupportedInput( "Binary data can only be encoded".to_string(), "value originates from here".into(), command_span, // This line requires the Value::Error {} match above. input.span(), - )), - span: command_span, - }, + ), + command_span, + ), }, - Value::String { - val, - span: value_span, - } => { + Value::String { val, .. } => { match base64_config.action_type { ActionType::Encode => { let mut enc_str = String::new(); @@ -160,22 +158,22 @@ fn action( } else { match String::from_utf8(decoded_value) { Ok(string_value) => Value::string(string_value, command_span), - Err(e) => Value::Error { - error: Box::new(ShellError::GenericError( + Err(e) => Value::error( + ShellError::GenericError( "base64 payload isn't a valid utf-8 sequence" .to_owned(), e.to_string(), - Some(*value_span), + Some(value_span), Some("consider using the `--binary` flag".to_owned()), Vec::new(), - )), - span: *value_span, - }, + ), + value_span, + ), } } } - Err(_) => Value::Error { - error: Box::new(ShellError::GenericError( + Err(_) => Value::error( + ShellError::GenericError( "value could not be base64 decoded".to_string(), format!( "invalid base64 input for character set {}", @@ -184,20 +182,20 @@ fn action( Some(command_span), None, Vec::new(), - )), - span: command_span, - }, + ), + command_span, + ), } } } } - other => Value::Error { - error: Box::new(ShellError::TypeMismatch { + other => Value::error( + ShellError::TypeMismatch { err_message: format!("string or binary, not {}", other.get_type()), span: other.span(), - }), - span: other.span(), - }, + }, + other.span(), + ), } } @@ -323,10 +321,7 @@ mod tests { #[test] fn base64_encode_binary() { - let word = Value::Binary { - val: vec![77, 97, 110], - span: Span::test_data(), - }; + let word = Value::binary(vec![77, 97, 110], Span::test_data()); let expected = Value::test_string("TWFu"); let actual = action( @@ -349,10 +344,7 @@ mod tests { #[test] fn base64_decode_binary_expect_error() { - let word = Value::Binary { - val: vec![77, 97, 110], - span: Span::test_data(), - }; + let word = Value::binary(vec![77, 97, 110], Span::test_data()); let actual = action( &word, diff --git a/crates/nu-command/src/strings/encode_decode/decode.rs b/crates/nu-command/src/strings/encode_decode/decode.rs index 1f1fa4d80..46a69b25d 100644 --- a/crates/nu-command/src/strings/encode_decode/decode.rs +++ b/crates/nu-command/src/strings/encode_decode/decode.rs @@ -47,10 +47,7 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"# Example { description: "Decode an UTF-16 string into nushell UTF-8 string", example: r#"0x[00 53 00 6F 00 6D 00 65 00 20 00 44 00 61 00 74 00 61] | decode utf-16be"#, - result: Some(Value::String { - val: "Some Data".to_owned(), - span: Span::test_data(), - }), + result: Some(Value::string("Some Data".to_owned(), Span::test_data())), }, ] } @@ -77,29 +74,29 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"# Some(encoding_name) => super::encoding::decode(head, encoding_name, &bytes), None => super::encoding::detect_encoding_name(head, input_span, &bytes) .map(|encoding| encoding.decode(&bytes).0.into_owned()) - .map(|s| Value::String { val: s, span: head }), + .map(|s| Value::string(s, head)), } .map(|val| val.into_pipeline_data()) } - PipelineData::Value(v, ..) => match v { - Value::Binary { - val: bytes, - span: input_span, - } => match encoding { - Some(encoding_name) => super::encoding::decode(head, encoding_name, &bytes), - None => super::encoding::detect_encoding_name(head, input_span, &bytes) - .map(|encoding| encoding.decode(&bytes).0.into_owned()) - .map(|s| Value::String { val: s, span: head }), + PipelineData::Value(v, ..) => { + let input_span = v.span(); + match v { + Value::Binary { val: bytes, .. } => match encoding { + Some(encoding_name) => super::encoding::decode(head, encoding_name, &bytes), + None => super::encoding::detect_encoding_name(head, input_span, &bytes) + .map(|encoding| encoding.decode(&bytes).0.into_owned()) + .map(|s| Value::string(s, head)), + } + .map(|val| val.into_pipeline_data()), + Value::Error { error, .. } => Err(*error), + _ => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "binary".into(), + wrong_type: v.get_type().to_string(), + dst_span: head, + src_span: v.span(), + }), } - .map(|val| val.into_pipeline_data()), - Value::Error { error, .. } => Err(*error), - _ => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "binary".into(), - wrong_type: v.get_type().to_string(), - dst_span: head, - src_span: v.span(), - }), - }, + } // This should be more precise, but due to difficulties in getting spans // from PipelineData::ListData, this is as it is. _ => Err(ShellError::UnsupportedInput( diff --git a/crates/nu-command/src/strings/encode_decode/encode.rs b/crates/nu-command/src/strings/encode_decode/encode.rs index 8e977165e..7cc1359c4 100644 --- a/crates/nu-command/src/strings/encode_decode/encode.rs +++ b/crates/nu-command/src/strings/encode_decode/encode.rs @@ -53,23 +53,23 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"# Example { description: "Encode an UTF-8 string into Shift-JIS", example: r#""負けると知って戦うのが、遥かに美しいのだ" | encode shift-jis"#, - result: Some(Value::Binary { - val: vec![ + result: Some(Value::binary( + vec![ 0x95, 0x89, 0x82, 0xaf, 0x82, 0xe9, 0x82, 0xc6, 0x92, 0x6d, 0x82, 0xc1, 0x82, 0xc4, 0x90, 0xed, 0x82, 0xa4, 0x82, 0xcc, 0x82, 0xaa, 0x81, 0x41, 0x97, 0x79, 0x82, 0xa9, 0x82, 0xc9, 0x94, 0xfc, 0x82, 0xb5, 0x82, 0xa2, 0x82, 0xcc, 0x82, 0xbe, ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Replace characters with HTML entities if they can't be encoded", example: r#""🎈" | encode -i shift-jis"#, - result: Some(Value::Binary { - val: vec![0x26, 0x23, 0x31, 0x32, 0x37, 0x38, 0x38, 0x30, 0x3b], - span: Span::test_data(), - }), + result: Some(Value::binary( + vec![0x26, 0x23, 0x31, 0x32, 0x37, 0x38, 0x38, 0x30, 0x3b], + Span::test_data(), + )), }, ] } @@ -95,19 +95,22 @@ documentation link at https://docs.rs/encoding_rs/latest/encoding_rs/#statics"# super::encoding::encode(head, encoding, &s.item, s.span, ignore_errors) .map(|val| val.into_pipeline_data()) } - PipelineData::Value(v, ..) => match v { - Value::String { val: s, span } => { - super::encoding::encode(head, encoding, &s, span, ignore_errors) - .map(|val| val.into_pipeline_data()) + PipelineData::Value(v, ..) => { + let span = v.span(); + match v { + Value::String { val: s, .. } => { + super::encoding::encode(head, encoding, &s, span, ignore_errors) + .map(|val| val.into_pipeline_data()) + } + Value::Error { error, .. } => Err(*error), + _ => Err(ShellError::OnlySupportsThisInputType { + exp_input_type: "string".into(), + wrong_type: v.get_type().to_string(), + dst_span: head, + src_span: v.span(), + }), } - Value::Error { error, .. } => Err(*error), - _ => Err(ShellError::OnlySupportsThisInputType { - exp_input_type: "string".into(), - wrong_type: v.get_type().to_string(), - dst_span: head, - src_span: v.span(), - }), - }, + } // This should be more precise, but due to difficulties in getting spans // from PipelineData::ListStream, this is as it is. _ => Err(ShellError::UnsupportedInput( diff --git a/crates/nu-command/src/strings/encode_decode/encoding.rs b/crates/nu-command/src/strings/encode_decode/encoding.rs index 1e4f7f748..1917184b3 100644 --- a/crates/nu-command/src/strings/encode_decode/encoding.rs +++ b/crates/nu-command/src/strings/encode_decode/encoding.rs @@ -34,10 +34,7 @@ pub fn decode( parse_encoding(encoding_name.span, &encoding_name.item) }?; let (result, ..) = encoding.decode(bytes); - Ok(Value::String { - val: result.into_owned(), - span: head, - }) + Ok(Value::string(result.into_owned(), head)) } pub fn encode( @@ -66,10 +63,7 @@ pub fn encode( vec![], )) } else { - Ok(Value::Binary { - val: result.into_owned(), - span: head, - }) + Ok(Value::binary(result.into_owned(), head)) } } diff --git a/crates/nu-command/src/strings/format/date.rs b/crates/nu-command/src/strings/format/date.rs index 6e4e05b2d..5c6c7b4e6 100644 --- a/crates/nu-command/src/strings/format/date.rs +++ b/crates/nu-command/src/strings/format/date.rs @@ -79,19 +79,19 @@ impl Command for FormatDate { Example { description: "Format a given date-time using the default format (RFC 2822).", example: r#"'2021-10-22 20:00:12 +01:00' | into datetime | format date"#, - result: Some(Value::String { - val: "Fri, 22 Oct 2021 20:00:12 +0100".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string( + "Fri, 22 Oct 2021 20:00:12 +0100".to_string(), + Span::test_data(), + )), }, Example { description: "Format a given date-time as a string using the default format (RFC 2822).", example: r#""2021-10-22 20:00:12 +01:00" | format date"#, - result: Some(Value::String { - val: "Fri, 22 Oct 2021 20:00:12 +0100".to_string(), - span: Span::test_data(), - }), + result: Some(Value::string( + "Fri, 22 Oct 2021 20:00:12 +0100".to_string(), + Span::test_data(), + )), }, Example { description: "Format the current date-time using a given format string.", @@ -126,17 +126,14 @@ where let format = date_time.format_localized(formatter, locale); match formatter_buf.write_fmt(format_args!("{format}")) { - Ok(_) => Value::String { - val: formatter_buf, - span, - }, - Err(_) => Value::Error { - error: Box::new(ShellError::TypeMismatch { + Ok(_) => Value::string(formatter_buf, span), + Err(_) => Value::error( + ShellError::TypeMismatch { err_message: "invalid format".to_string(), span, - }), + }, span, - }, + ), } } @@ -151,39 +148,28 @@ fn format_helper(value: Value, formatter: &str, formatter_span: Span, head_span: Err(e) => e, } } - _ => Value::Error { - error: Box::new(ShellError::DatetimeParseError( - value.debug_value(), - head_span, - )), - span: head_span, - }, + _ => Value::error( + ShellError::DatetimeParseError(value.debug_value(), head_span), + head_span, + ), } } fn format_helper_rfc2822(value: Value, span: Span) -> Value { + let val_span = value.span(); match value { - Value::Date { val, span: _ } => Value::String { - val: val.to_rfc2822(), - span, - }, - Value::String { - val, - span: val_span, - } => { + Value::Date { val, .. } => Value::string(val.to_rfc2822(), span), + Value::String { val, .. } => { let dt = parse_date_from_string(&val, val_span); match dt { - Ok(x) => Value::String { - val: x.to_rfc2822(), - span, - }, + Ok(x) => Value::string(x.to_rfc2822(), span), Err(e) => e, } } - _ => Value::Error { - error: Box::new(ShellError::DatetimeParseError(value.debug_value(), span)), + _ => Value::error( + ShellError::DatetimeParseError(value.debug_value(), span), span, - }, + ), } } diff --git a/crates/nu-command/src/strings/format/duration.rs b/crates/nu-command/src/strings/format/duration.rs index 66e6c29ad..264851f06 100644 --- a/crates/nu-command/src/strings/format/duration.rs +++ b/crates/nu-command/src/strings/format/duration.rs @@ -111,14 +111,12 @@ impl Command for FormatDuration { } fn format_value_impl(val: &Value, arg: &Arguments, span: Span) -> Value { + let inner_span = val.span(); match val { - Value::Duration { - val: inner, - span: inner_span, - } => { + Value::Duration { val: inner, .. } => { let duration = *inner; let float_precision = arg.float_precision; - match convert_inner_to_unit(duration, &arg.format_value, span, *inner_span) { + match convert_inner_to_unit(duration, &arg.format_value, span, inner_span) { Ok(d) => { let unit = if &arg.format_value == "us" { "µs" @@ -126,33 +124,24 @@ fn format_value_impl(val: &Value, arg: &Arguments, span: Span) -> Value { &arg.format_value }; if d.fract() == 0.0 { - Value::String { - val: format!("{} {}", d, unit), - span: *inner_span, - } + Value::string(format!("{} {}", d, unit), inner_span) } else { - Value::String { - val: format!("{:.float_precision$} {}", d, unit), - span: *inner_span, - } + Value::string(format!("{:.float_precision$} {}", d, unit), inner_span) } } - Err(e) => Value::Error { - error: Box::new(e), - span: *inner_span, - }, + Err(e) => Value::error(e, inner_span), } } Value::Error { .. } => val.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "filesize".into(), wrong_type: val.get_type().to_string(), dst_span: span, src_span: val.span(), - }), + }, span, - }, + ), } } diff --git a/crates/nu-command/src/strings/format/filesize.rs b/crates/nu-command/src/strings/format/filesize.rs index ab0446724..fb0992256 100644 --- a/crates/nu-command/src/strings/format/filesize.rs +++ b/crates/nu-command/src/strings/format/filesize.rs @@ -103,22 +103,23 @@ impl Command for FormatFilesize { } fn format_value_impl(val: &Value, arg: &Arguments, span: Span) -> Value { + let value_span = val.span(); match val { - Value::Filesize { val, span } => Value::String { + Value::Filesize { val, .. } => Value::string( // don't need to concern about metric, we just format units by what user input. - val: format_filesize(*val, &arg.format_value, None), - span: *span, - }, + format_filesize(*val, &arg.format_value, None), + span, + ), Value::Error { .. } => val.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "filesize".into(), wrong_type: val.get_type().to_string(), dst_span: span, - src_span: val.span(), - }), + src_span: value_span, + }, span, - }, + ), } } diff --git a/crates/nu-command/src/strings/parse.rs b/crates/nu-command/src/strings/parse.rs index 01affd492..6e25bb761 100644 --- a/crates/nu-command/src/strings/parse.rs +++ b/crates/nu-command/src/strings/parse.rs @@ -43,13 +43,13 @@ impl Command for Parse { } fn examples(&self) -> Vec { - let result = Value::List { - vals: vec![Value::test_record(Record { + let result = Value::list( + vec![Value::test_record(Record { cols: vec!["foo".to_string(), "bar".to_string()], vals: vec![Value::test_string("hi"), Value::test_string("there")], })], - span: Span::test_data(), - }; + Span::test_data(), + ); vec![ Example { @@ -65,19 +65,19 @@ impl Command for Parse { Example { description: "Parse a string using fancy-regex named capture group pattern", example: "\"foo bar.\" | parse -r '\\s*(?\\w+)(?=\\.)'", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["name".to_string()], vals: vec![Value::test_string("bar")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Parse a string using fancy-regex capture group pattern", example: "\"foo! bar.\" | parse -r '(\\w+)(?=\\.)|(\\w+)(?=!)'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["capture0".to_string(), "capture1".to_string()], vals: vec![Value::test_string(""), Value::test_string("foo")], @@ -87,34 +87,34 @@ impl Command for Parse { vals: vec![Value::test_string("bar"), Value::test_string("")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Parse a string using fancy-regex look behind pattern", example: "\" @another(foo bar) \" | parse -r '\\s*(?<=[() ])(@\\w+)(\\([^)]*\\))?\\s*'", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["capture0".to_string(), "capture1".to_string()], vals: vec![ Value::test_string("@another"), Value::test_string("(foo bar)"), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Parse a string using fancy-regex look ahead atomic group pattern", example: "\"abcd\" | parse -r '^a(bc(?=d)|b)cd$'", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["capture0".to_string()], vals: vec![Value::test_string("b")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -342,14 +342,14 @@ impl Iterator for ParseStreamer { let Some(v) = self.stream.next() else { return None }; let Ok(s) = v.as_string() else { - return Some(Value::Error { - error: Box::new(ShellError::PipelineMismatch { + return Some(Value::error ( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: self.span, src_span: v.span(), - }), - span: v.span(), - }) + }, + v.span(), + )) }; let parsed = stream_helper( @@ -401,24 +401,19 @@ impl Iterator for ParseStreamerExternal { let chunk = match chunk { Some(Ok(chunk)) => chunk, - Some(Err(err)) => { - return Some(Value::Error { - error: Box::new(err), - span: self.span, - }) - } + Some(Err(err)) => return Some(Value::error(err, self.span)), _ => return None, }; let Ok(chunk) = String::from_utf8(chunk) else { - return Some(Value::Error { - error: Box::new(ShellError::PipelineMismatch { + return Some(Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: self.span, src_span: self.span, - }), - span: self.span, - }) + }, + self.span, + )) }; stream_helper( @@ -444,16 +439,16 @@ fn stream_helper( let captures = match c { Ok(c) => c, Err(e) => { - return Some(Value::Error { - error: Box::new(ShellError::GenericError( + return Some(Value::error( + ShellError::GenericError( "Error with regular expression captures".into(), e.to_string(), Some(span), Some(e.to_string()), Vec::new(), - )), + ), span, - }) + )) } }; diff --git a/crates/nu-command/src/strings/size.rs b/crates/nu-command/src/strings/size.rs index 96562df45..45b934a19 100644 --- a/crates/nu-command/src/strings/size.rs +++ b/crates/nu-command/src/strings/size.rs @@ -121,27 +121,22 @@ fn size( } input.map( move |v| { + let value_span = v.span(); // First, obtain the span. If this fails, propagate the error that results. - let value_span = match &v { - Value::Error { error, span } => { - return Value::Error { - error: error.clone(), - span: *span, - } - } - v => v.span(), - }; + if let Value::Error { error, .. } = v { + return Value::error(*error, span); + } // Now, check if it's a string. match v.as_string() { Ok(s) => counter(&s, span), - Err(_) => Value::Error { - error: Box::new(ShellError::PipelineMismatch { + Err(_) => Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: span, src_span: value_span, - }), + }, span, - }, + ), } }, engine_state.ctrlc.clone(), diff --git a/crates/nu-command/src/strings/split/chars.rs b/crates/nu-command/src/strings/split/chars.rs index 4f47667b4..68d0c7d02 100644 --- a/crates/nu-command/src/strings/split/chars.rs +++ b/crates/nu-command/src/strings/split/chars.rs @@ -46,28 +46,28 @@ impl Command for SubCommand { Example { description: "Split the string into a list of characters", example: "'hello' | split chars", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("h"), Value::test_string("e"), Value::test_string("l"), Value::test_string("l"), Value::test_string("o"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split on grapheme clusters", example: "'🇯🇵ほげ' | split chars -g", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("🇯🇵"), Value::test_string("ほ"), Value::test_string("げ"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split multiple strings into lists of characters", @@ -118,16 +118,14 @@ fn split_chars( } fn split_chars_helper(v: &Value, name: Span, graphemes: bool) -> Value { + let span = v.span(); match v { - Value::Error { error, span } => Value::Error { - error: error.clone(), - span: *span, - }, + Value::Error { error, .. } => Value::error(*error.clone(), span), v => { let v_span = v.span(); if let Ok(s) = v.as_string() { - Value::List { - vals: if graphemes { + Value::list( + if graphemes { s.graphemes(true) .collect::>() .into_iter() @@ -140,17 +138,17 @@ fn split_chars_helper(v: &Value, name: Span, graphemes: bool) -> Value { .map(move |x| Value::string(x, v_span)) .collect() }, - span: v_span, - } + v_span, + ) } else { - Value::Error { - error: Box::new(ShellError::PipelineMismatch { + Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: name, src_span: v_span, - }), - span: name, - } + }, + name, + ) } } } diff --git a/crates/nu-command/src/strings/split/column.rs b/crates/nu-command/src/strings/split/column.rs index 0e89727c3..16a1d8799 100644 --- a/crates/nu-command/src/strings/split/column.rs +++ b/crates/nu-command/src/strings/split/column.rs @@ -63,8 +63,8 @@ impl Command for SubCommand { Example { description: "Split a string into columns by the specified separator", example: "'a--b--c' | split column '--'", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec![ "column1".to_string(), "column2".to_string(), @@ -76,14 +76,14 @@ impl Command for SubCommand { Value::test_string("c"), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a string into columns of char and remove the empty columns", example: "'abc' | split column -c ''", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec![ "column1".to_string(), "column2".to_string(), @@ -95,14 +95,14 @@ impl Command for SubCommand { Value::test_string("c"), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a list of strings into a table", example: "['a-b' 'c-d'] | split column -", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["column1".to_string(), "column2".to_string()], vals: vec![Value::test_string("a"), Value::test_string("b")], @@ -112,14 +112,14 @@ impl Command for SubCommand { vals: vec![Value::test_string("c"), Value::test_string("d")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a list of strings into a table, ignoring padding", example: r"['a - b' 'c - d'] | split column -r '\s*-\s*'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["column1".to_string(), "column2".to_string()], vals: vec![Value::test_string("a"), Value::test_string("b")], @@ -129,8 +129,8 @@ impl Command for SubCommand { vals: vec![Value::test_string("c"), Value::test_string("d")], }), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -203,21 +203,18 @@ fn split_column_helper( } else { match v { Value::Error { error, .. } => { - vec![Value::Error { - error: Box::new(*error.clone()), - span: head, - }] + vec![Value::error(*error.clone(), head)] } v => { let span = v.span(); - vec![Value::Error { - error: Box::new(ShellError::PipelineMismatch { + vec![Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: head, src_span: span, - }), + }, span, - }] + )] } } } diff --git a/crates/nu-command/src/strings/split/command.rs b/crates/nu-command/src/strings/split/command.rs index f6a96a50d..7daf68a19 100644 --- a/crates/nu-command/src/strings/split/command.rs +++ b/crates/nu-command/src/strings/split/command.rs @@ -34,16 +34,16 @@ impl Command for SplitCommand { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &SplitCommand.signature(), &SplitCommand.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/strings/split/list.rs b/crates/nu-command/src/strings/split/list.rs index 428947de4..158b4cae7 100644 --- a/crates/nu-command/src/strings/split/list.rs +++ b/crates/nu-command/src/strings/split/list.rs @@ -56,100 +56,97 @@ impl Command for SubCommand { Example { description: "Split a list of chars into two lists", example: "[a, b, c, d, e, f, g] | split list d", - result: Some(Value::List { - vals: vec![ - Value::List { - vals: vec![ + result: Some(Value::list( + vec![ + Value::list( + vec![ Value::test_string("a"), Value::test_string("b"), Value::test_string("c"), ], - span: Span::test_data(), - }, - Value::List { - vals: vec![ + Span::test_data(), + ), + Value::list( + vec![ Value::test_string("e"), Value::test_string("f"), Value::test_string("g"), ], - span: Span::test_data(), - }, + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a list of lists into two lists of lists", example: "[[1,2], [2,3], [3,4]] | split list [2,3]", - result: Some(Value::List { - vals: vec![ - Value::List { - vals: vec![Value::List { - vals: vec![Value::test_int(1), Value::test_int(2)], - span: Span::test_data(), - }], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::List { - vals: vec![Value::test_int(3), Value::test_int(4)], - span: Span::test_data(), - }], - span: Span::test_data(), - }, + result: Some(Value::list( + vec![ + Value::list( + vec![Value::list( + vec![Value::test_int(1), Value::test_int(2)], + Span::test_data(), + )], + Span::test_data(), + ), + Value::list( + vec![Value::list( + vec![Value::test_int(3), Value::test_int(4)], + Span::test_data(), + )], + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a list of chars into two lists", example: "[a, b, c, d, a, e, f, g] | split list a", - result: Some(Value::List { - vals: vec![ - Value::List { - vals: vec![ + result: Some(Value::list( + vec![ + Value::list( + vec![ Value::test_string("b"), Value::test_string("c"), Value::test_string("d"), ], - span: Span::test_data(), - }, - Value::List { - vals: vec![ + Span::test_data(), + ), + Value::list( + vec![ Value::test_string("e"), Value::test_string("f"), Value::test_string("g"), ], - span: Span::test_data(), - }, + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a list of chars into lists based on multiple characters", example: r"[a, b, c, d, a, e, f, g] | split list -r '(b|e)'", - result: Some(Value::List { - vals: vec![ - Value::List { - vals: vec![Value::test_string("a")], - span: Span::test_data(), - }, - Value::List { - vals: vec![ + result: Some(Value::list( + vec![ + Value::list(vec![Value::test_string("a")], Span::test_data()), + Value::list( + vec![ Value::test_string("c"), Value::test_string("d"), Value::test_string("a"), ], - span: Span::test_data(), - }, - Value::List { - vals: vec![Value::test_string("f"), Value::test_string("g")], - span: Span::test_data(), - }, + Span::test_data(), + ), + Value::list( + vec![Value::test_string("f"), Value::test_string("g")], + Span::test_data(), + ), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -211,10 +208,7 @@ fn split_list( for val in iter { if matcher.compare(&val)? { if !temp_list.is_empty() { - returned_list.push(Value::List { - vals: temp_list.clone(), - span: call.head, - }); + returned_list.push(Value::list(temp_list.clone(), call.head)); temp_list = Vec::new(); } } else { @@ -222,16 +216,9 @@ fn split_list( } } if !temp_list.is_empty() { - returned_list.push(Value::List { - vals: temp_list.clone(), - span: call.head, - }); + returned_list.push(Value::list(temp_list.clone(), call.head)); } - Ok(Value::List { - vals: returned_list, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::list(returned_list, call.head).into_pipeline_data()) } #[cfg(test)] diff --git a/crates/nu-command/src/strings/split/row.rs b/crates/nu-command/src/strings/split/row.rs index d22502072..c3fc16713 100644 --- a/crates/nu-command/src/strings/split/row.rs +++ b/crates/nu-command/src/strings/split/row.rs @@ -62,54 +62,54 @@ impl Command for SubCommand { Example { description: "Split a string into rows of char", example: "'abc' | split row ''", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string(""), Value::test_string("a"), Value::test_string("b"), Value::test_string("c"), Value::test_string(""), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a string into rows by the specified separator", example: "'a--b--c' | split row '--'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("a"), Value::test_string("b"), Value::test_string("c"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a string by '-'", example: "'-a-b-c-' | split row '-'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string(""), Value::test_string("a"), Value::test_string("b"), Value::test_string("c"), Value::test_string(""), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Split a string by regex", example: r"'a b c' | split row -r '\s+'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("a"), Value::test_string("b"), Value::test_string("c"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -146,12 +146,10 @@ fn split_row( } fn split_row_helper(v: &Value, regex: &Regex, max_split: Option, name: Span) -> Vec { + let span = v.span(); match v { - Value::Error { error, span } => { - vec![Value::Error { - error: Box::new(*error.clone()), - span: *span, - }] + Value::Error { error, .. } => { + vec![Value::error(*error.clone(), span)] } v => { let v_span = v.span(); @@ -168,14 +166,14 @@ fn split_row_helper(v: &Value, regex: &Regex, max_split: Option, name: Sp .collect(), } } else { - vec![Value::Error { - error: Box::new(ShellError::PipelineMismatch { + vec![Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: name, src_span: v_span, - }), - span: name, - }] + }, + name, + )] } } } diff --git a/crates/nu-command/src/strings/split/words.rs b/crates/nu-command/src/strings/split/words.rs index 4bc50b2d3..fd4d0edda 100644 --- a/crates/nu-command/src/strings/split/words.rs +++ b/crates/nu-command/src/strings/split/words.rs @@ -73,23 +73,23 @@ impl Command for SubCommand { Example { description: "Split the string's words into separate rows", example: "'hello world' | split words", - result: Some(Value::List { - vals: vec![Value::test_string("hello"), Value::test_string("world")], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_string("hello"), Value::test_string("world")], + Span::test_data(), + )), }, Example { description: "Split the string's words, of at least 3 characters, into separate rows", example: "'hello to the world' | split words -l 3", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("hello"), Value::test_string("the"), Value::test_string("world"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: @@ -152,12 +152,10 @@ fn split_words_helper(v: &Value, word_length: Option, span: Span, graphem // [^\p{L}\'] = do not match any unicode uppercase or lowercase letters or apostrophes // Let's go with the unicode one in hopes that it works on more than just ascii characters let regex_replace = Regex::new(r"[^\p{L}\']").expect("regular expression error"); + let v_span = v.span(); match v { - Value::Error { error, span } => Value::Error { - error: Box::new(*error.clone()), - span: *span, - }, + Value::Error { error, .. } => Value::error(*error.clone(), v_span), v => { let v_span = v.span(); if let Ok(s) = v.as_string() { @@ -189,19 +187,16 @@ fn split_words_helper(v: &Value, word_length: Option, span: Span, graphem } }) .collect::>(); - Value::List { - vals: words, - span: v_span, - } + Value::list(words, v_span) } else { - Value::Error { - error: Box::new(ShellError::PipelineMismatch { + Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: span, src_span: v_span, - }), - span, - } + }, + v_span, + ) } } } diff --git a/crates/nu-command/src/strings/str_/case/capitalize.rs b/crates/nu-command/src/strings/str_/case/capitalize.rs index e5c714de7..fd66d14e7 100644 --- a/crates/nu-command/src/strings/str_/case/capitalize.rs +++ b/crates/nu-command/src/strings/str_/case/capitalize.rs @@ -68,13 +68,13 @@ impl Command for SubCommand { Example { description: "Capitalize a column in a table", example: "[[lang, gems]; [nu_test, 100]] | str capitalize lang", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["lang".to_string(), "gems".to_string()], vals: vec![Value::test_string("Nu_test"), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -98,10 +98,7 @@ fn operate( let r = ret.update_cell_path(&path.members, Box::new(move |old| action(old, head))); if let Err(error) = r { - return Value::Error { - error: Box::new(error), - span: head, - }; + return Value::error(error, head); } } ret @@ -113,20 +110,17 @@ fn operate( fn action(input: &Value, head: Span) -> Value { match input { - Value::String { val, .. } => Value::String { - val: uppercase_helper(val), - span: head, - }, + Value::String { val, .. } => Value::string(uppercase_helper(val), head), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/case/downcase.rs b/crates/nu-command/src/strings/str_/case/downcase.rs index b054b1c3e..3918689de 100644 --- a/crates/nu-command/src/strings/str_/case/downcase.rs +++ b/crates/nu-command/src/strings/str_/case/downcase.rs @@ -68,24 +68,24 @@ impl Command for SubCommand { Example { description: "Downcase contents", example: "[[ColA ColB]; [Test ABC]] | str downcase ColA", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string()], vals: vec![Value::test_string("test"), Value::test_string("ABC")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Downcase contents", example: "[[ColA ColB]; [Test ABC]] | str downcase ColA ColB", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string()], vals: vec![Value::test_string("test"), Value::test_string("abc")], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -109,10 +109,7 @@ fn operate( let r = ret.update_cell_path(&path.members, Box::new(move |old| action(old, head))); if let Err(error) = r { - return Value::Error { - error: Box::new(error), - span: head, - }; + return Value::error(error, head); } } ret @@ -124,20 +121,17 @@ fn operate( fn action(input: &Value, head: Span) -> Value { match input { - Value::String { val, .. } => Value::String { - val: val.to_ascii_lowercase(), - span: head, - }, + Value::String { val, .. } => Value::string(val.to_ascii_lowercase(), head), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/case/mod.rs b/crates/nu-command/src/strings/str_/case/mod.rs index c602a4c31..afd934fb4 100644 --- a/crates/nu-command/src/strings/str_/case/mod.rs +++ b/crates/nu-command/src/strings/str_/case/mod.rs @@ -51,19 +51,16 @@ where { let case_operation = args.case_operation; match input { - Value::String { val, .. } => Value::String { - val: case_operation(val), - span: head, - }, + Value::String { val, .. } => Value::string(case_operation(val), head), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/case/str_.rs b/crates/nu-command/src/strings/str_/case/str_.rs index 6cfd59b71..a0731972a 100644 --- a/crates/nu-command/src/strings/str_/case/str_.rs +++ b/crates/nu-command/src/strings/str_/case/str_.rs @@ -34,16 +34,16 @@ impl Command for Str { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help( + Ok(Value::string( + get_full_help( &Str.signature(), &Str.examples(), engine_state, stack, self.is_parser_keyword(), ), - span: call.head, - } + call.head, + ) .into_pipeline_data()) } } diff --git a/crates/nu-command/src/strings/str_/case/upcase.rs b/crates/nu-command/src/strings/str_/case/upcase.rs index a0b61a708..fc17e60c4 100644 --- a/crates/nu-command/src/strings/str_/case/upcase.rs +++ b/crates/nu-command/src/strings/str_/case/upcase.rs @@ -78,10 +78,7 @@ fn operate( let r = ret.update_cell_path(&path.members, Box::new(move |old| action(old, head))); if let Err(error) = r { - return Value::Error { - error: Box::new(error), - span: head, - }; + return Value::error(error, head); } } ret @@ -93,20 +90,17 @@ fn operate( fn action(input: &Value, head: Span) -> Value { match input { - Value::String { val: s, .. } => Value::String { - val: s.to_uppercase(), - span: head, - }, + Value::String { val: s, .. } => Value::string(s.to_uppercase(), head), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/contains.rs b/crates/nu-command/src/strings/str_/contains.rs index 0e3b65bb7..f88d10f63 100644 --- a/crates/nu-command/src/strings/str_/contains.rs +++ b/crates/nu-command/src/strings/str_/contains.rs @@ -97,24 +97,24 @@ impl Command for SubCommand { Example { description: "Check if input contains string in a table", example: " [[ColA ColB]; [test 100]] | str contains -i 'E' ColA", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string()], vals: vec![Value::test_bool(true), Value::test_int(100)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Check if input contains string in a table", example: " [[ColA ColB]; [test hello]] | str contains 'e' ColA ColB", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string()], vals: vec![Value::test_bool(true), Value::test_bool(true)], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Check if input string contains 'banana'", @@ -124,26 +124,26 @@ impl Command for SubCommand { Example { description: "Check if list contains string", example: "[one two three] | str contains o", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_bool(true), Value::test_bool(true), Value::test_bool(false), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Check if list does not contain string", example: "[one two three] | str contains -n o", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_bool(false), Value::test_bool(false), Value::test_bool(true), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -182,15 +182,15 @@ fn action( head, ), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/distance.rs b/crates/nu-command/src/strings/str_/distance.rs index a6cdc9d27..3000b8128 100644 --- a/crates/nu-command/src/strings/str_/distance.rs +++ b/crates/nu-command/src/strings/str_/distance.rs @@ -80,15 +80,15 @@ impl Command for SubCommand { Example { description: "Compute edit distance between strings in table and another string, using cell paths", example: "[{a: 'nutshell' b: 'numetal'}] | str distance 'nushell' 'a' 'b'", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list ( + vec![ Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![Value::test_int(1), Value::test_int(4)], }) ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Compute edit distance between strings in record and another string, using cell paths", @@ -111,15 +111,15 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { Value::int(distance as i64, head) } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/ends_with.rs b/crates/nu-command/src/strings/str_/ends_with.rs index ba2d44609..dc3e33788 100644 --- a/crates/nu-command/src/strings/str_/ends_with.rs +++ b/crates/nu-command/src/strings/str_/ends_with.rs @@ -105,15 +105,15 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { Value::bool(ends_with, head) } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/expand.rs b/crates/nu-command/src/strings/str_/expand.rs index 1c8fed4bc..f25f8cd80 100644 --- a/crates/nu-command/src/strings/str_/expand.rs +++ b/crates/nu-command/src/strings/str_/expand.rs @@ -43,142 +43,142 @@ impl Command for SubCommand { Example { description: "Define a range inside braces to produce a list of string.", example: "\"{3..5}\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("3"), Value::test_string("4"), Value::test_string("5") ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Ignore the next character after the backslash ('\\')", example: "'A{B\\,,C}' | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("AB,"), Value::test_string("AC"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Commas that are not inside any braces need to be skipped.", example: "'Welcome\\, {home,mon ami}!' | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("Welcome, home!"), Value::test_string("Welcome, mon ami!"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Use double backslashes to add a backslash.", example: "'A{B\\\\,C}' | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("AB\\"), Value::test_string("AC"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Export comma separated values inside braces (`{}`) to a string list.", example: "\"{apple,banana,cherry}\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("apple"), Value::test_string("banana"), Value::test_string("cherry") ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "If the piped data is path, you may want to use --path flag, or else manually replace the backslashes with double backslashes.", example: "'C:\\{Users,Windows}' | str expand --path", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("C:\\Users"), Value::test_string("C:\\Windows"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Brace expressions can be used one after another.", example: "\"A{b,c}D{e,f}G\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("AbDeG"), Value::test_string("AbDfG"), Value::test_string("AcDeG"), Value::test_string("AcDfG"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Collection may include an empty item. It can be put at the start of the list.", example: "\"A{,B,C}\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("A"), Value::test_string("AB"), Value::test_string("AC"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Empty item can be at the end of the collection.", example: "\"A{B,C,}\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("AB"), Value::test_string("AC"), Value::test_string("A"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Empty item can be in the middle of the collection.", example: "\"A{B,,C}\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("AB"), Value::test_string("A"), Value::test_string("AC"), ], - span: Span::test_data() - },) + Span::test_data() + )), }, Example { description: "Also, it is possible to use one inside another. Here is a real-world example, that creates files:", example: "\"A{B{1,3},C{2,5}}D\" | str expand", - result: Some(Value::List{ - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("AB1D"), Value::test_string("AB3D"), Value::test_string("AC2D"), Value::test_string("AC5D"), ], - span: Span::test_data() - },) + Span::test_data() + )), } ] } @@ -203,14 +203,14 @@ impl Command for SubCommand { let contents = if is_path { s.replace('\\', "\\\\") } else { s }; str_expand(&contents, span, v.span()) } - Err(_) => Value::Error { - error: Box::new(ShellError::PipelineMismatch { + Err(_) => Value::error( + ShellError::PipelineMismatch { exp_input_type: "string".into(), dst_span: span, src_span: value_span, - }), + }, span, - }, + ), } }, engine_state.ctrlc.clone(), @@ -230,17 +230,17 @@ fn str_expand(contents: &str, span: Span, value_span: Span) -> Value { Ok(node) => { match expand(&node) { Ok(possibilities) => { - Value::List { vals: possibilities.iter().map(|e| Value::string(e,span)).collect::>(), span } + Value::list(possibilities.iter().map(|e| Value::string(e,span)).collect::>(), span) }, Err(e) => match e { - bracoxide::ExpansionError::NumConversionFailed(s) => Value::Error { error: - Box::new(ShellError::GenericError("Number Conversion Failed".to_owned(), format!("Number conversion failed at {s}."), Some(value_span), Some("Expected number, found text. Range format is `{M..N}`, where M and N are numeric values representing the starting and ending limits.".to_owned()), vec![])), + bracoxide::ExpansionError::NumConversionFailed(s) => Value::error( + ShellError::GenericError("Number Conversion Failed".to_owned(), format!("Number conversion failed at {s}."), Some(value_span), Some("Expected number, found text. Range format is `{M..N}`, where M and N are numeric values representing the starting and ending limits.".to_owned()), vec![]), span, - }, + ), }, } }, - Err(e) => Value::Error { error: Box::new( + Err(e) => Value::error( match e { ParsingError::NoTokens => ShellError::PipelineEmpty { dst_span: value_span }, ParsingError::OBraExpected(s) => ShellError::GenericError("Opening Brace Expected".to_owned(), format!("Opening brace is expected at {s}."), Some(value_span), Some("In brace syntax, we use equal amount of opening (`{`) and closing (`}`). Please, take a look at the examples.".to_owned()), vec![]), @@ -255,31 +255,31 @@ fn str_expand(contents: &str, span: Span, value_span: Span) -> Value { ParsingError::ExtraOBra(s) => ShellError::GenericError("Extra Opening Brace".to_owned(), format!("Used extra opening brace at {s}."), Some(value_span), Some("To escape opening brace use backslash, e.g. `\\{`".to_owned()), vec![]), ParsingError::NothingInBraces(s) => ShellError::GenericError("Nothing In Braces".to_owned(), format!("Nothing found inside braces at {s}."), Some(value_span), Some("Please provide valid content within the braces. Additionally, you can safely remove it, not needed.".to_owned()), vec![]), } - ), + , span, - } + ) } }, Err(e) => match e { - TokenizationError::EmptyContent => Value::Error { - error: Box::new(ShellError::PipelineEmpty { dst_span: value_span }), - span: value_span, - }, - TokenizationError::FormatNotSupported => Value::Error { - error: Box::new( + TokenizationError::EmptyContent => Value::error( + ShellError::PipelineEmpty { dst_span: value_span }, + value_span, + ), + TokenizationError::FormatNotSupported => Value::error( + ShellError::GenericError( "Format Not Supported".to_owned(), "Usage of only `{` or `}`. Brace Expansion syntax, needs to have equal amount of opening (`{`) and closing (`}`)".to_owned(), Some(value_span), Some("In brace expansion syntax, it is important to have an equal number of opening (`{`) and closing (`}`) braces. Please ensure that you provide a balanced pair of braces in your brace expansion pattern.".to_owned()), vec![] - )), - span: value_span, - }, - TokenizationError::NoBraces => Value::Error { - error: Box::new(ShellError::GenericError("No Braces".to_owned(), "At least one `{}` brace expansion expected.".to_owned(), Some(value_span), Some("Please, examine the examples.".to_owned()), vec![])), - span: value_span, - } + ), + value_span, + ), + TokenizationError::NoBraces => Value::error( + ShellError::GenericError("No Braces".to_owned(), "At least one `{}` brace expansion expected.".to_owned(), Some(value_span), Some("Please, examine the examples.".to_owned()), vec![]), + value_span, + ) }, } } @@ -292,51 +292,33 @@ mod tests { fn dots() { assert_eq!( str_expand("{a.b.c,d}", Span::test_data(), Span::test_data()), - Value::List { - vals: vec![ - Value::String { - val: String::from("a.b.c"), - span: Span::test_data(), - }, - Value::String { - val: String::from("d"), - span: Span::test_data(), - }, + Value::list( + vec![ + Value::string(String::from("a.b.c"), Span::test_data(),), + Value::string(String::from("d"), Span::test_data(),) ], - span: Span::test_data(), - } + Span::test_data(), + ) ); assert_eq!( str_expand("{1.2.3,a}", Span::test_data(), Span::test_data()), - Value::List { - vals: vec![ - Value::String { - val: String::from("1.2.3"), - span: Span::test_data(), - }, - Value::String { - val: String::from("a"), - span: Span::test_data(), - }, + Value::list( + vec![ + Value::string(String::from("1.2.3"), Span::test_data(),), + Value::string(String::from("a"), Span::test_data(),) ], - span: Span::test_data(), - } + Span::test_data(), + ) ); assert_eq!( str_expand("{a-1.2,b}", Span::test_data(), Span::test_data()), - Value::List { - vals: vec![ - Value::String { - val: String::from("a-1.2"), - span: Span::test_data(), - }, - Value::String { - val: String::from("b"), - span: Span::test_data(), - }, + Value::list( + vec![ + Value::string(String::from("a-1.2"), Span::test_data(),), + Value::string(String::from("b"), Span::test_data(),) ], - span: Span::test_data(), - } + Span::test_data(), + ) ); } diff --git a/crates/nu-command/src/strings/str_/index_of.rs b/crates/nu-command/src/strings/str_/index_of.rs index fd49b14ed..6b830f925 100644 --- a/crates/nu-command/src/strings/str_/index_of.rs +++ b/crates/nu-command/src/strings/str_/index_of.rs @@ -161,10 +161,7 @@ fn action( } Err(processing_error) => { let err = processing_error("could not find `index-of`", head); - return Value::Error { - error: Box::new(err), - span: head, - }; + return Value::error(err, head); } } } else { @@ -198,15 +195,15 @@ fn action( } } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } @@ -262,17 +259,9 @@ mod tests { fn returns_index_of_next_substring() { let word = Value::test_string("Cargo.Cargo"); let range = Range { - from: Value::Int { - val: 1, - span: Span::test_data(), - }, - incr: Value::Int { - val: 1, - span: Span::test_data(), - }, - to: Value::Nothing { - span: Span::test_data(), - }, + from: Value::int(1, Span::test_data()), + incr: Value::int(1, Span::test_data()), + to: Value::nothing(Span::test_data()), inclusion: RangeInclusion::Inclusive, }; @@ -293,18 +282,10 @@ mod tests { fn index_does_not_exist_due_to_end_index() { let word = Value::test_string("Cargo.Banana"); let range = Range { - from: Value::Nothing { - span: Span::test_data(), - }, + from: Value::nothing(Span::test_data()), inclusion: RangeInclusion::Inclusive, - incr: Value::Int { - val: 1, - span: Span::test_data(), - }, - to: Value::Int { - val: 5, - span: Span::test_data(), - }, + incr: Value::int(1, Span::test_data()), + to: Value::int(5, Span::test_data()), }; let options = Arguments { @@ -324,18 +305,9 @@ mod tests { fn returns_index_of_nums_in_middle_due_to_index_limit_from_both_ends() { let word = Value::test_string("123123123"); let range = Range { - from: Value::Int { - val: 2, - span: Span::test_data(), - }, - incr: Value::Int { - val: 1, - span: Span::test_data(), - }, - to: Value::Int { - val: 6, - span: Span::test_data(), - }, + from: Value::int(2, Span::test_data()), + incr: Value::int(1, Span::test_data()), + to: Value::int(6, Span::test_data()), inclusion: RangeInclusion::Inclusive, }; @@ -356,18 +328,9 @@ mod tests { fn index_does_not_exists_due_to_strict_bounds() { let word = Value::test_string("123456"); let range = Range { - from: Value::Int { - val: 2, - span: Span::test_data(), - }, - incr: Value::Int { - val: 1, - span: Span::test_data(), - }, - to: Value::Int { - val: 5, - span: Span::test_data(), - }, + from: Value::int(2, Span::test_data()), + incr: Value::int(1, Span::test_data()), + to: Value::int(5, Span::test_data()), inclusion: RangeInclusion::RightExclusive, }; @@ -386,10 +349,7 @@ mod tests { #[test] fn use_utf8_bytes() { - let word = Value::String { - val: String::from("🇯🇵ほげ ふが ぴよ"), - span: Span::test_data(), - }; + let word = Value::string(String::from("🇯🇵ほげ ふが ぴよ"), Span::test_data()); let options = Arguments { substring: String::from("ふが"), diff --git a/crates/nu-command/src/strings/str_/join.rs b/crates/nu-command/src/strings/str_/join.rs index 561c908ac..5f1c850d4 100644 --- a/crates/nu-command/src/strings/str_/join.rs +++ b/crates/nu-command/src/strings/str_/join.rs @@ -70,11 +70,7 @@ impl Command for StrJoin { strings.join("") }; - Ok(Value::String { - val: output, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(output, call.head).into_pipeline_data()) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/strings/str_/length.rs b/crates/nu-command/src/strings/str_/length.rs index 4c3571687..696ec0bf3 100644 --- a/crates/nu-command/src/strings/str_/length.rs +++ b/crates/nu-command/src/strings/str_/length.rs @@ -102,10 +102,10 @@ impl Command for SubCommand { Example { description: "Return the lengths of multiple strings", example: "['hi' 'there'] | str length", - result: Some(Value::List { - vals: vec![Value::test_int(2), Value::test_int(5)], - span: Span::test_data(), - }), + result: Some(Value::list( + vec![Value::test_int(2), Value::test_int(5)], + Span::test_data(), + )), }, ] } @@ -135,15 +135,15 @@ fn action(input: &Value, arg: &Arguments, head: Span) -> Value { head, ), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } @@ -153,10 +153,7 @@ mod test { #[test] fn use_utf8_bytes() { - let word = Value::String { - val: String::from("🇯🇵ほげ ふが ぴよ"), - span: Span::test_data(), - }; + let word = Value::string(String::from("🇯🇵ほげ ふが ぴよ"), Span::test_data()); let options = Arguments { cell_paths: None, diff --git a/crates/nu-command/src/strings/str_/replace.rs b/crates/nu-command/src/strings/str_/replace.rs index b84a3c9b7..d47e242df 100644 --- a/crates/nu-command/src/strings/str_/replace.rs +++ b/crates/nu-command/src/strings/str_/replace.rs @@ -149,8 +149,8 @@ impl Command for SubCommand { description: "Find and replace all occurrences of find string in table using regular expression", example: "[[ColA ColB ColC]; [abc abc ads]] | str replace -ar 'b' 'z' ColA ColC", - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list ( + vec![Value::test_record(Record { cols: vec!["ColA".to_string(), "ColB".to_string(), "ColC".to_string()], vals: vec![ Value::test_string("azc"), @@ -158,8 +158,8 @@ impl Command for SubCommand { Value::test_string("ads"), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }, Example { description: "Find and replace all occurrences of find string in record using regular expression", @@ -225,15 +225,9 @@ fn action( if *no_regex { // just use regular string replacement vs regular expressions if *all { - Value::String { - val: val.replace(find_str, replace_str), - span: head, - } + Value::string(val.replace(find_str, replace_str), head) } else { - Value::String { - val: val.replacen(find_str, replace_str, 1), - span: head, - } + Value::string(val.replacen(find_str, replace_str, 1), head) } } else { // use regular expressions to replace strings @@ -247,50 +241,50 @@ fn action( match regex { Ok(re) => { if *all { - Value::String { - val: { + Value::string( + { if *literal_replace { re.replace_all(val, NoExpand(replace_str)).to_string() } else { re.replace_all(val, replace_str).to_string() } }, - span: head, - } + head, + ) } else { - Value::String { - val: { + Value::string( + { if *literal_replace { re.replace(val, NoExpand(replace_str)).to_string() } else { re.replace(val, replace_str).to_string() } }, - span: head, - } + head, + ) } } - Err(e) => Value::Error { - error: Box::new(ShellError::IncorrectValue { + Err(e) => Value::error( + ShellError::IncorrectValue { msg: format!("Regex error: {e}"), val_span: find.span, call_span: head, - }), - span: find.span, - }, + }, + find.span, + ), } } } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/reverse.rs b/crates/nu-command/src/strings/str_/reverse.rs index a05431e44..b9d55adcb 100644 --- a/crates/nu-command/src/strings/str_/reverse.rs +++ b/crates/nu-command/src/strings/str_/reverse.rs @@ -64,14 +64,14 @@ impl Command for SubCommand { Example { description: "Reverse multiple strings in a list", example: "['Nushell' 'is' 'cool'] | str reverse", - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_string("llehsuN"), Value::test_string("si"), Value::test_string("looc"), ], - span: Span::test_data(), - }), + Span::test_data(), + )), }, ] } @@ -79,20 +79,17 @@ impl Command for SubCommand { fn action(input: &Value, _arg: &CellPathOnlyArgs, head: Span) -> Value { match input { - Value::String { val, .. } => Value::String { - val: val.chars().rev().collect::(), - span: head, - }, + Value::String { val, .. } => Value::string(val.chars().rev().collect::(), head), Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/starts_with.rs b/crates/nu-command/src/strings/str_/starts_with.rs index 21a4f5046..5c1ed82d7 100644 --- a/crates/nu-command/src/strings/str_/starts_with.rs +++ b/crates/nu-command/src/strings/str_/starts_with.rs @@ -118,15 +118,15 @@ fn action( Value::bool(starts_with, head) } Value::Error { .. } => input.clone(), - _ => Value::Error { - error: Box::new(ShellError::OnlySupportsThisInputType { + _ => Value::error( + ShellError::OnlySupportsThisInputType { exp_input_type: "string".into(), wrong_type: input.get_type().to_string(), dst_span: head, src_span: input.span(), - }), - span: head, - }, + }, + head, + ), } } diff --git a/crates/nu-command/src/strings/str_/substring.rs b/crates/nu-command/src/strings/str_/substring.rs index 22d353e3d..5de61e43b 100644 --- a/crates/nu-command/src/strings/str_/substring.rs +++ b/crates/nu-command/src/strings/str_/substring.rs @@ -144,15 +144,15 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { if start < len && end >= 0 { match start.cmp(&end) { Ordering::Equal => Value::string("", head), - Ordering::Greater => Value::Error { - error: Box::new(ShellError::TypeMismatch { + Ordering::Greater => Value::error( + ShellError::TypeMismatch { err_message: "End must be greater than or equal to Start".to_string(), span: head, - }), - span: head, - }, - Ordering::Less => Value::String { - val: { + }, + head, + ), + Ordering::Less => Value::string( + { if end == isize::max_value() { if args.graphemes { s.graphemes(true) @@ -181,8 +181,8 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { .to_string() } }, - span: head, - }, + head, + ), } } else { Value::string("", head) @@ -190,16 +190,16 @@ fn action(input: &Value, args: &Arguments, head: Span) -> Value { } // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => Value::Error { - error: Box::new(ShellError::UnsupportedInput( + other => Value::error( + ShellError::UnsupportedInput( "Only string values are supported".into(), format!("input type: {:?}", other.get_type()), head, // This line requires the Value::Error match above. other.span(), - )), - span: head, - }, + ), + head, + ), } } @@ -279,10 +279,7 @@ mod tests { #[test] fn use_utf8_bytes() { - let word = Value::String { - val: String::from("🇯🇵ほげ ふが ぴよ"), - span: Span::test_data(), - }; + let word = Value::string(String::from("🇯🇵ほげ ふが ぴよ"), Span::test_data()); let options = Arguments { cell_paths: None, diff --git a/crates/nu-command/src/strings/str_/trim/trim_.rs b/crates/nu-command/src/strings/str_/trim/trim_.rs index 7fdef6f03..6b1ca5f96 100644 --- a/crates/nu-command/src/strings/str_/trim/trim_.rs +++ b/crates/nu-command/src/strings/str_/trim/trim_.rs @@ -172,48 +172,46 @@ fn action(input: &Value, arg: &Arguments, head: Span) -> Value { let trim_side = &arg.trim_side; let mode = &arg.mode; match input { - Value::String { val: s, .. } => Value::String { - val: trim(s, char_, trim_side), - span: head, - }, + Value::String { val: s, .. } => Value::string(trim(s, char_, trim_side), head), // Propagate errors by explicitly matching them before the final case. Value::Error { .. } => input.clone(), - other => match mode { - ActionMode::Global => match other { - Value::Record { val: record, span } => { - let new_vals = record.vals.iter().map(|v| action(v, arg, head)).collect(); + other => { + let span = other.span(); - Value::record( - Record { - cols: record.cols.to_vec(), - vals: new_vals, - }, - *span, + match mode { + ActionMode::Global => match other { + Value::Record { val: record, .. } => { + let new_vals = record.vals.iter().map(|v| action(v, arg, head)).collect(); + + Value::record( + Record { + cols: record.cols.to_vec(), + vals: new_vals, + }, + span, + ) + } + Value::List { vals, .. } => { + let new_vals = vals.iter().map(|v| action(v, arg, head)).collect(); + + Value::list(new_vals, span) + } + _ => input.clone(), + }, + ActionMode::Local => { + Value::error( + ShellError::UnsupportedInput( + "Only string values are supported".into(), + format!("input type: {:?}", other.get_type()), + head, + // This line requires the Value::Error match above. + other.span(), + ), + head, ) } - Value::List { vals, span } => { - let new_vals = vals.iter().map(|v| action(v, arg, head)).collect(); - - Value::List { - vals: new_vals, - span: *span, - } - } - _ => input.clone(), - }, - ActionMode::Local => { - Value::Error { - error: Box::new(ShellError::UnsupportedInput( - "Only string values are supported".into(), - format!("input type: {:?}", other.get_type()), - head, - // This line requires the Value::Error match above. - other.span(), - )), - span: head, - } } - }, + } } } @@ -261,13 +259,12 @@ mod tests { } fn make_list(vals: Vec<&str>) -> Value { - Value::List { - vals: vals - .iter() + Value::list( + vals.iter() .map(|x| Value::test_string(x.to_string())) .collect(), - span: Span::test_data(), - } + Span::test_data(), + ) } #[test] @@ -422,22 +419,22 @@ mod tests { #[test] fn global_trim_left_table() { - let row = Value::List { - vals: vec![ + let row = Value::list( + vec![ Value::test_string(" a "), Value::test_int(65), Value::test_string(" d"), ], - span: Span::test_data(), - }; - let expected = Value::List { - vals: vec![ + Span::test_data(), + ); + let expected = Value::list( + vec![ Value::test_string("a "), Value::test_int(65), Value::test_string("d"), ], - span: Span::test_data(), - }; + Span::test_data(), + ); let args = Arguments { to_trim: None, @@ -522,22 +519,22 @@ mod tests { #[test] fn global_trim_right_table() { - let row = Value::List { - vals: vec![ + let row = Value::list( + vec![ Value::test_string(" a "), Value::test_int(65), Value::test_string(" d"), ], - span: Span::test_data(), - }; - let expected = Value::List { - vals: vec![ + Span::test_data(), + ); + let expected = Value::list( + vec![ Value::test_string(" a"), Value::test_int(65), Value::test_string(" d"), ], - span: Span::test_data(), - }; + Span::test_data(), + ); let args = Arguments { to_trim: None, trim_side: TrimSide::Right, diff --git a/crates/nu-command/src/system/complete.rs b/crates/nu-command/src/system/complete.rs index 1012e4d9b..d0bc21c6b 100644 --- a/crates/nu-command/src/system/complete.rs +++ b/crates/nu-command/src/system/complete.rs @@ -60,15 +60,9 @@ impl Command for Complete { .spawn(move || { let stderr = stderr.into_bytes()?; if let Ok(st) = String::from_utf8(stderr.item.clone()) { - Ok::<_, ShellError>(Value::String { - val: st, - span: stderr.span, - }) + Ok::<_, ShellError>(Value::string(st, stderr.span)) } else { - Ok::<_, ShellError>(Value::Binary { - val: stderr.item, - span: stderr.span, - }) + Ok::<_, ShellError>(Value::binary(stderr.item, stderr.span)) } }) .expect("failed to create thread"), diff --git a/crates/nu-command/src/system/nu_check.rs b/crates/nu-command/src/system/nu_check.rs index cd10d4b5f..ae612ae8c 100644 --- a/crates/nu-command/src/system/nu_check.rs +++ b/crates/nu-command/src/system/nu_check.rs @@ -60,8 +60,9 @@ impl Command for NuCheck { None, vec![])); } + let span = input.span().unwrap_or(call.head); match input { - PipelineData::Value(Value::String { val, span }, ..) => { + PipelineData::Value(Value::String { val, .. }, ..) => { let contents = Vec::from(val); if is_all { heuristic_parse(&mut working_set, None, &contents, is_debug, call.head) diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 207328b24..b59b7afa9 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -506,10 +506,10 @@ impl ExternalCommand { "{cause}: oops, process '{commandname}' core dumped" )) ); - let _ = exit_code_tx.send(Value::Error { - error: Box::new(ShellError::ExternalCommand { label: "core dumped".to_string(), help: format!("{cause}: child process '{commandname}' core dumped"), span: head }), - span: head, - }); + let _ = exit_code_tx.send(Value::error ( + ShellError::ExternalCommand { label: "core dumped".to_string(), help: format!("{cause}: child process '{commandname}' core dumped"), span: head }, + head, + )); return Ok(()); } } diff --git a/crates/nu-command/src/system/sys.rs b/crates/nu-command/src/system/sys.rs index 072bfbac0..2f92298a6 100644 --- a/crates/nu-command/src/system/sys.rs +++ b/crates/nu-command/src/system/sys.rs @@ -38,10 +38,7 @@ impl Command for Sys { _input: PipelineData, ) -> Result { let span = call.span(); - let ret = Value::LazyRecord { - val: Box::new(SysResult { span }), - span, - }; + let ret = Value::lazy_record(Box::new(SysResult { span }), span); Ok(ret.into_pipeline_data()) } @@ -100,10 +97,7 @@ impl LazyRecord<'_> for SysResult { } fn clone_value(&self, span: Span) -> Value { - Value::LazyRecord { - val: Box::new((*self).clone()), - span, - } + Value::lazy_record(Box::new((*self).clone()), span) } } @@ -133,7 +127,7 @@ pub fn disks(span: Span) -> Value { output.push(Value::record(record, span)); } - Value::List { vals: output, span } + Value::list(output, span) } pub fn net(span: Span) -> Value { @@ -151,7 +145,7 @@ pub fn net(span: Span) -> Value { output.push(Value::record(record, span)); } - Value::List { vals: output, span } + Value::list(output, span) } pub fn cpu(span: Span) -> Value { @@ -187,7 +181,7 @@ pub fn cpu(span: Span) -> Value { output.push(Value::record(record, span)); } - Value::List { vals: output, span } + Value::list(output, span) } pub fn mem(span: Span) -> Value { @@ -264,10 +258,7 @@ pub fn host(span: Span) -> Value { for user in sys.users() { let mut groups = vec![]; for group in user.groups() { - groups.push(Value::String { - val: trim_cstyle_null(group.to_string()), - span, - }); + groups.push(Value::string(trim_cstyle_null(group.to_string()), span)); } let record = record! { @@ -305,5 +296,5 @@ pub fn temp(span: Span) -> Value { output.push(Value::record(record, span)); } - Value::List { vals: output, span } + Value::list(output, span) } diff --git a/crates/nu-command/src/viewers/griddle.rs b/crates/nu-command/src/viewers/griddle.rs index 95e586267..a250aa83f 100644 --- a/crates/nu-command/src/viewers/griddle.rs +++ b/crates/nu-command/src/viewers/griddle.rs @@ -243,10 +243,7 @@ fn create_grid_output( if let Some(grid_display) = grid.fit_into_width(cols as usize) { Value::string(grid_display.to_string(), call.head) } else { - Value::String { - val: format!("Couldn't fit grid into {cols} columns!"), - span: call.head, - } + Value::string(format!("Couldn't fit grid into {cols} columns!"), call.head) } .into_pipeline_data(), ) diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index dacadc628..1bd81690b 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -129,10 +129,7 @@ impl Command for Table { // if list argument is present we just need to return a list of supported table themes if list { - let val = Value::List { - vals: supported_table_modes(), - span: Span::test_data(), - }; + let val = Value::list(supported_table_modes(), Span::test_data()); return Ok(val.into_pipeline_data()); } @@ -165,8 +162,8 @@ impl Command for Table { Example { description: "Render data in table view", example: r#"[[a b]; [1 2] [3 4]] | table"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![Value::test_int(1), Value::test_int(2)], @@ -177,13 +174,13 @@ impl Command for Table { }), ], span, - }), + )), }, Example { description: "Render data in table view (expanded)", example: r#"[[a b]; [1 2] [2 [4 4]]] | table --expand"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![Value::test_int(1), Value::test_int(2)], @@ -194,13 +191,13 @@ impl Command for Table { }), ], span, - }), + )), }, Example { description: "Render data in table view (collapsed)", example: r#"[[a b]; [1 2] [2 [4 4]]] | table --collapse"#, - result: Some(Value::List { - vals: vec![ + result: Some(Value::list( + vec![ Value::test_record(Record { cols: vec!["a".to_string(), "b".to_string()], vals: vec![Value::test_int(1), Value::test_int(2)], @@ -211,7 +208,7 @@ impl Command for Table { }), ], span, - }), + )), }, ] } @@ -229,6 +226,7 @@ fn handle_table_command( let ctrlc = engine_state.ctrlc.clone(); let config = get_config(engine_state, stack); + let span = input.span().unwrap_or(call.head); match input { PipelineData::ExternalStream { .. } => Ok(input), PipelineData::Value(Value::Binary { val, .. }, ..) => Ok(PipelineData::ExternalStream { @@ -270,7 +268,7 @@ fn handle_table_command( ctrlc, metadata, ), - PipelineData::Value(Value::Record { val, span }, ..) => { + PipelineData::Value(Value::Record { val, .. }, ..) => { let term_width = get_width_param(term_width); handle_record( @@ -302,7 +300,7 @@ fn handle_table_command( // instead of stdout. Err(*error) } - PipelineData::Value(Value::CustomValue { val, span }, ..) => { + PipelineData::Value(Value::CustomValue { val, .. }, ..) => { let base_pipeline = val.to_base_value(span)?.into_pipeline_data(); Table.run(engine_state, stack, call, base_pipeline) } @@ -363,10 +361,7 @@ fn handle_record( } }; - let val = Value::String { - val: result, - span: call.head, - }; + let val = Value::string(result, call.head); Ok(val.into_pipeline_data()) } @@ -421,7 +416,7 @@ fn build_table_batch( ExpandedTable::new(limit, flatten, sep).build_list(&vals, opts) } TableView::Collapsed => { - let value = Value::List { vals, span }; + let value = Value::list(vals, span); CollapsedTable::build(value, opts) } } @@ -436,6 +431,7 @@ fn handle_row_stream( ctrlc: Option>, metadata: Option>, ) -> Result { + let head = call.head; let stream = match metadata.as_deref() { // First, `ls` sources: Some(PipelineMetadata { @@ -457,8 +453,9 @@ fn handle_row_stream( while idx < record.len() { // Only the name column gets special colors, for now if record.cols[idx] == "name" { - if let Some(Value::String { val, span }) = record.vals.get(idx) { - let val = render_path_name(val, &config, &ls_colors, *span); + let span = record.vals.get(idx).map(|v| v.span()).unwrap_or(head); + if let Some(Value::String { val, .. }) = record.vals.get(idx) { + let val = render_path_name(val, &config, &ls_colors, span); if let Some(val) = val { record.vals[idx] = val; } @@ -490,7 +487,9 @@ fn handle_row_stream( if record.cols[idx] != "name" { // Simple routine to grab the hex code, convert to a style, // then place it in a new Value::String. - if let Some(Value::String { val, span }) = record.vals.get(idx) { + + let span = record.vals.get(idx).map(|v| v.span()).unwrap_or(head); + if let Some(Value::String { val, .. }) = record.vals.get(idx) { let s = match color_from_hex(val) { Ok(c) => match c { // .normal() just sets the text foreground color. @@ -499,11 +498,11 @@ fn handle_row_stream( }, Err(_) => nu_ansi_term::Style::default(), }; - record.vals[idx] = Value::String { + record.vals[idx] = Value::string( // Apply the style (ANSI codes) to the string - val: s.paint(val).to_string(), - span: *span, - }; + s.paint(val).to_string(), + span, + ); } } idx += 1; @@ -814,7 +813,7 @@ fn render_path_name( ); let val = ansi_style.paint(full_path_link).to_string(); - Some(Value::String { val, span }) + Some(Value::string(val, span)) } #[derive(Debug)] diff --git a/crates/nu-engine/src/documentation.rs b/crates/nu-engine/src/documentation.rs index d95b3baa6..0f95968f2 100644 --- a/crates/nu-engine/src/documentation.rs +++ b/crates/nu-engine/src/documentation.rs @@ -231,7 +231,7 @@ fn get_documentation( redirect_stderr: true, parser_info: HashMap::new(), }, - PipelineData::Value(Value::List { vals, span }, None), + PipelineData::Value(Value::list(vals, span), None), ) { if let Ok((str, ..)) = result.collect_string_strict(span) { let _ = writeln!(long_desc, "\n{G}Input/output types{RESET}:"); diff --git a/crates/nu-engine/src/env.rs b/crates/nu-engine/src/env.rs index d28d8fe71..67a94c85b 100644 --- a/crates/nu-engine/src/env.rs +++ b/crates/nu-engine/src/env.rs @@ -191,15 +191,16 @@ pub fn current_dir_str(engine_state: &EngineState, stack: &Stack) -> Result Result { if let Some(pwd) = working_set.get_env_var(PWD_ENV) { + let span = pwd.span(); match pwd { - Value::String { val, span } => { + Value::String { val, .. } => { if Path::new(val).is_absolute() { Ok(val.clone()) } else { Err(ShellError::GenericError( "Invalid current directory".to_string(), format!("The 'PWD' environment variable must be set to an absolute path. Found: '{val}'"), - Some(*span), + Some(span), None, Vec::new() )) @@ -383,38 +384,39 @@ fn get_converted_value( }, ]; - if let Ok(Value::Closure { - val: block_id, - span: from_span, - .. - }) = env_conversions.follow_cell_path_not_from_user_input(path_members, false) - { - let block = engine_state.get_block(block_id); + if let Ok(v) = env_conversions.follow_cell_path_not_from_user_input(path_members, false) { + let from_span = v.span(); + match v { + Value::Closure { val: block_id, .. } => { + let block = engine_state.get_block(block_id); - if let Some(var) = block.signature.get_positional(0) { - let mut stack = stack.gather_captures(engine_state, &block.captures); - if let Some(var_id) = &var.var_id { - stack.add_var(*var_id, orig_val.clone()); + if let Some(var) = block.signature.get_positional(0) { + let mut stack = stack.gather_captures(engine_state, &block.captures); + if let Some(var_id) = &var.var_id { + stack.add_var(*var_id, orig_val.clone()); + } + + let result = eval_block( + engine_state, + &mut stack, + block, + PipelineData::new_with_metadata(None, val_span), + true, + true, + ); + + match result { + Ok(data) => ConversionResult::Ok(data.into_value(val_span)), + Err(e) => ConversionResult::ConversionError(e), + } + } else { + ConversionResult::ConversionError(ShellError::MissingParameter { + param_name: "block input".into(), + span: from_span, + }) + } } - - let result = eval_block( - engine_state, - &mut stack, - block, - PipelineData::new_with_metadata(None, val_span), - true, - true, - ); - - match result { - Ok(data) => ConversionResult::Ok(data.into_value(val_span)), - Err(e) => ConversionResult::ConversionError(e), - } - } else { - ConversionResult::ConversionError(ShellError::MissingParameter { - param_name: "block input".into(), - span: from_span, - }) + _ => ConversionResult::CellPathError, } } else { ConversionResult::CellPathError @@ -428,48 +430,47 @@ fn ensure_path(scope: &mut HashMap, env_path_name: &str) -> Optio let mut error = None; // If PATH/Path is still a string, force-convert it to a list - match scope.get(env_path_name) { - Some(Value::String { val, span }) => { - // Force-split path into a list - let span = *span; - let paths = std::env::split_paths(val) - .map(|p| Value::String { - val: p.to_string_lossy().to_string(), - span, - }) - .collect(); + if let Some(value) = scope.get(env_path_name) { + let span = value.span(); + match value { + Value::String { val, .. } => { + // Force-split path into a list + let paths = std::env::split_paths(val) + .map(|p| Value::string(p.to_string_lossy().to_string(), span)) + .collect(); + + scope.insert(env_path_name.to_string(), Value::list(paths, span)); + } + Value::List { vals, .. } => { + // Must be a list of strings + if !vals.iter().all(|v| matches!(v, Value::String { .. })) { + error = error.or_else(|| { + Some(ShellError::GenericError( + format!("Wrong {env_path_name} environment variable value"), + format!("{env_path_name} must be a list of strings"), + Some(span), + None, + Vec::new(), + )) + }); + } + } + + val => { + // All other values are errors + let span = val.span(); - scope.insert(env_path_name.to_string(), Value::List { vals: paths, span }); - } - Some(Value::List { vals, span }) => { - // Must be a list of strings - if !vals.iter().all(|v| matches!(v, Value::String { .. })) { error = error.or_else(|| { Some(ShellError::GenericError( format!("Wrong {env_path_name} environment variable value"), format!("{env_path_name} must be a list of strings"), - Some(*span), + Some(span), None, Vec::new(), )) }); } } - Some(val) => { - // All other values are errors - let span = val.span(); - - error = error.or_else(|| { - Some(ShellError::GenericError( - format!("Wrong {env_path_name} environment variable value"), - format!("{env_path_name} must be a list of strings"), - Some(span), - None, - Vec::new(), - )) - }); - } - None => { /* not preset, do nothing */ } } error diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index d7e431016..ad92502c5 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -33,7 +33,7 @@ pub fn eval_call( input: PipelineData, ) -> Result { if nu_utils::ctrl_c::was_pressed(&engine_state.ctrlc) { - return Ok(Value::Nothing { span: call.head }.into_pipeline_data()); + return Ok(Value::nothing(call.head).into_pipeline_data()); } let decl = engine_state.get_decl(call.decl_id); @@ -49,11 +49,7 @@ pub fn eval_call( caller_stack, decl.is_parser_keyword(), ); - Ok(Value::String { - val: full_help, - span: call.head, - } - .into_pipeline_data()) + Ok(Value::string(full_help, call.head).into_pipeline_data()) } else if let Some(block_id) = decl.get_block_id() { let block = engine_state.get_block(block_id); @@ -101,10 +97,7 @@ pub fn eval_call( rest_positional .var_id .expect("Internal error: rest positional parameter lacks var_id"), - Value::List { - vals: rest_items, - span, - }, + Value::list(rest_items, span), ) } @@ -145,7 +138,7 @@ pub fn eval_call( } else if let Some(value) = named.default_value { callee_stack.add_var(var_id, value); } else { - callee_stack.add_var(var_id, Value::Nothing { span: call.head }) + callee_stack.add_var(var_id, Value::nothing(call.head)) } } } @@ -278,10 +271,7 @@ pub fn eval_expression( Expr::Bool(b) => Ok(Value::bool(*b, expr.span)), Expr::Int(i) => Ok(Value::int(*i, expr.span)), Expr::Float(f) => Ok(Value::float(*f, expr.span)), - Expr::Binary(b) => Ok(Value::Binary { - val: b.clone(), - span: expr.span, - }), + Expr::Binary(b) => Ok(Value::binary(b.clone(), expr.span)), Expr::ValueWithUnit(e, unit) => match eval_expression(engine_state, stack, e)? { Value::Int { val, .. } => compute(val, unit.item, unit.span), x => Err(ShellError::CantConvert { @@ -295,46 +285,40 @@ pub fn eval_expression( let from = if let Some(f) = from { eval_expression(engine_state, stack, f)? } else { - Value::Nothing { span: expr.span } + Value::nothing(expr.span) }; let next = if let Some(s) = next { eval_expression(engine_state, stack, s)? } else { - Value::Nothing { span: expr.span } + Value::nothing(expr.span) }; let to = if let Some(t) = to { eval_expression(engine_state, stack, t)? } else { - Value::Nothing { span: expr.span } + Value::nothing(expr.span) }; - Ok(Value::Range { - val: Box::new(Range::new(expr.span, from, next, to, operator)?), - span: expr.span, - }) + Ok(Value::range( + Range::new(expr.span, from, next, to, operator)?, + expr.span, + )) } Expr::Var(var_id) => eval_variable(engine_state, stack, *var_id, expr.span), - Expr::VarDecl(_) => Ok(Value::Nothing { span: expr.span }), - Expr::CellPath(cell_path) => Ok(Value::CellPath { - val: cell_path.clone(), - span: expr.span, - }), + Expr::VarDecl(_) => Ok(Value::nothing(expr.span)), + Expr::CellPath(cell_path) => Ok(Value::cell_path(cell_path.clone(), expr.span)), Expr::FullCellPath(cell_path) => { let value = eval_expression(engine_state, stack, &cell_path.head)?; value.follow_cell_path(&cell_path.tail, false) } - Expr::ImportPattern(_) => Ok(Value::Nothing { span: expr.span }), + Expr::ImportPattern(_) => Ok(Value::nothing(expr.span)), Expr::Overlay(_) => { let name = String::from_utf8_lossy(engine_state.get_span_contents(expr.span)).to_string(); - Ok(Value::String { - val: name, - span: expr.span, - }) + Ok(Value::string(name, expr.span)) } Expr::Call(call) => { // FIXME: protect this collect with ctrl-c @@ -354,16 +338,10 @@ pub fn eval_expression( )? .into_value(span)) } - Expr::DateTime(dt) => Ok(Value::Date { - val: *dt, - span: expr.span, - }), - Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }), - Expr::MatchPattern(pattern) => Ok(Value::MatchPattern { - val: pattern.clone(), - span: expr.span, - }), - Expr::MatchBlock(_) => Ok(Value::Nothing { span: expr.span }), // match blocks are handled by `match` + Expr::DateTime(dt) => Ok(Value::date(*dt, expr.span)), + Expr::Operator(_) => Ok(Value::nothing(expr.span)), + Expr::MatchPattern(pattern) => Ok(Value::match_pattern(*pattern.clone(), expr.span)), + Expr::MatchBlock(_) => Ok(Value::nothing(expr.span)), // match blocks are handled by `match` Expr::UnaryNot(expr) => { let lhs = eval_expression(engine_state, stack, expr)?; match lhs { @@ -567,25 +545,15 @@ pub fn eval_expression( for var_id in &block.captures { captures.insert(*var_id, stack.get_var(*var_id, expr.span)?); } - Ok(Value::Closure { - val: *block_id, - captures, - span: expr.span, - }) + Ok(Value::closure(*block_id, captures, expr.span)) } - Expr::Block(block_id) => Ok(Value::Block { - val: *block_id, - span: expr.span, - }), + Expr::Block(block_id) => Ok(Value::block(*block_id, expr.span)), Expr::List(x) => { let mut output = vec![]; for expr in x { output.push(eval_expression(engine_state, stack, expr)?); } - Ok(Value::List { - vals: output, - span: expr.span, - }) + Ok(Value::list(output, expr.span)) } Expr::Record(fields) => { let mut record = Record::new(); @@ -629,10 +597,7 @@ pub fn eval_expression( expr.span, )); } - Ok(Value::List { - vals: output_rows, - span: expr.span, - }) + Ok(Value::list(output_rows, expr.span)) } Expr::Keyword(_, _, expr) => eval_expression(engine_state, stack, expr), Expr::StringInterpolation(exprs) => { @@ -647,15 +612,9 @@ pub fn eval_expression( .into_iter() .into_pipeline_data(None) .collect_string("", config) - .map(|x| Value::String { - val: x, - span: expr.span, - }) + .map(|x| Value::string(x, expr.span)) } - Expr::String(s) => Ok(Value::String { - val: s.clone(), - span: expr.span, - }), + Expr::String(s) => Ok(Value::string(s.clone(), expr.span)), Expr::Filepath(s) => { let cwd = current_dir_str(engine_state, stack)?; let path = expand_path_with(s, cwd); @@ -678,9 +637,9 @@ pub fn eval_expression( Ok(Value::string(path.to_string_lossy(), expr.span)) } - Expr::Signature(_) => Ok(Value::Nothing { span: expr.span }), - Expr::Garbage => Ok(Value::Nothing { span: expr.span }), - Expr::Nothing => Ok(Value::Nothing { span: expr.span }), + Expr::Signature(_) => Ok(Value::nothing(expr.span)), + Expr::Garbage => Ok(Value::nothing(expr.span)), + Expr::Nothing => Ok(Value::nothing(expr.span)), } } @@ -1152,10 +1111,10 @@ pub fn eval_block( } (Err(error), true) => { input = PipelineData::Value( - Value::Error { - error: Box::new(error), - span: Span::unknown(), // FIXME: where does this span come from? - }, + Value::error( + error, + Span::unknown(), // FIXME: where does this span come from? + ), None, ) } @@ -1301,11 +1260,8 @@ fn collect_profiling_metadata( Ok((PipelineData::ExternalStream { .. }, ..)) => { Value::string("raw stream", element_span) } - Ok((PipelineData::Empty, ..)) => Value::Nothing { span: element_span }, - Err(err) => Value::Error { - error: Box::new(err.clone()), - span: element_span, - }, + Ok((PipelineData::Empty, ..)) => Value::nothing(element_span), + Err(err) => Value::error(err.clone(), element_span), }; record.push("value", value); diff --git a/crates/nu-engine/src/scope.rs b/crates/nu-engine/src/scope.rs index 787caeeac..04ad70ecc 100644 --- a/crates/nu-engine/src/scope.rs +++ b/crates/nu-engine/src/scope.rs @@ -141,15 +141,10 @@ impl<'e, 's> ScopeData<'e, 's> { .map(|(input_type, output_type)| { ( input_type.to_shape().to_string(), - Value::List { - vals: self.collect_signature_entries( - input_type, - output_type, - signature, - span, - ), + Value::list( + self.collect_signature_entries(input_type, output_type, signature, span), span, - }, + ), ) }) .collect::>(); @@ -162,10 +157,10 @@ impl<'e, 's> ScopeData<'e, 's> { let any_type = &Type::Any; sigs.push(( any_type.to_shape().to_string(), - Value::List { - vals: self.collect_signature_entries(any_type, any_type, signature, span), + Value::list( + self.collect_signature_entries(any_type, any_type, signature, span), span, - }, + ), )); } sigs.sort_unstable_by(|(k1, _), (k2, _)| k1.cmp(k2)); @@ -518,10 +513,7 @@ impl<'e, 's> ScopeData<'e, 's> { let export_env_block = module.env_block.map_or_else( || Value::nothing(span), - |block_id| Value::Block { - val: block_id, - span, - }, + |block_id| Value::block(block_id, span), ); let module_usage = self diff --git a/crates/nu-explore/src/commands/config.rs b/crates/nu-explore/src/commands/config.rs index 0c37e9b8b..1dde0f449 100644 --- a/crates/nu-explore/src/commands/config.rs +++ b/crates/nu-explore/src/commands/config.rs @@ -168,8 +168,5 @@ fn create_default_value() -> Value { ) }; - Value::List { - vals: vec![record(0), record(1), record(2)], - span, - } + Value::list(vec![record(0), record(1), record(2)], span) } diff --git a/crates/nu-explore/src/commands/help.rs b/crates/nu-explore/src/commands/help.rs index ae3b19ce9..46ae96130 100644 --- a/crates/nu-explore/src/commands/help.rs +++ b/crates/nu-explore/src/commands/help.rs @@ -172,10 +172,7 @@ fn help_frame_data( Value::record(Record { cols, vals }, NuSpan::unknown()) }) .collect(); - let commands = Value::List { - vals: commands, - span: NuSpan::unknown(), - }; + let commands = Value::list(commands, NuSpan::unknown()); collect_input(commands) } @@ -199,10 +196,7 @@ fn help_manual_data(manual: &HelpManual, aliases: &[String]) -> (Vec, Ve }) .collect(); - let arguments = Value::List { - vals: arguments, - span: NuSpan::unknown(), - }; + let arguments = Value::list(arguments, NuSpan::unknown()); let examples = manual .examples @@ -217,10 +211,7 @@ fn help_manual_data(manual: &HelpManual, aliases: &[String]) -> (Vec, Ve ) }) .collect(); - let examples = Value::List { - vals: examples, - span: NuSpan::unknown(), - }; + let examples = Value::list(examples, NuSpan::unknown()); let inputs = manual .input @@ -236,10 +227,7 @@ fn help_manual_data(manual: &HelpManual, aliases: &[String]) -> (Vec, Ve ) }) .collect(); - let inputs = Value::List { - vals: inputs, - span: NuSpan::unknown(), - }; + let inputs = Value::list(inputs, NuSpan::unknown()); let configuration = manual .config_options @@ -258,10 +246,7 @@ fn help_manual_data(manual: &HelpManual, aliases: &[String]) -> (Vec, Ve ) }) .collect(); - let values = Value::List { - vals: values, - span: NuSpan::unknown(), - }; + let values = Value::list(values, NuSpan::unknown()); Value::record( record! { @@ -274,10 +259,7 @@ fn help_manual_data(manual: &HelpManual, aliases: &[String]) -> (Vec, Ve ) }) .collect(); - let configuration = Value::List { - vals: configuration, - span: NuSpan::unknown(), - }; + let configuration = Value::list(configuration, NuSpan::unknown()); let name = nu_str(&manual.name); let aliases = nu_str(&aliases.join(", ")); diff --git a/crates/nu-explore/src/explore.rs b/crates/nu-explore/src/explore.rs index 23c40335f..e385bfb58 100644 --- a/crates/nu-explore/src/explore.rs +++ b/crates/nu-explore/src/explore.rs @@ -98,10 +98,7 @@ impl Command for Explore { Ok(Some(value)) => Ok(PipelineData::Value(value, None)), Ok(None) => Ok(PipelineData::Value(Value::default(), None)), Err(err) => Ok(PipelineData::Value( - Value::Error { - error: Box::new(err.into()), - span: call.head, - }, + Value::error(err.into(), call.head), None, )), } diff --git a/crates/nu-explore/src/nu_common/table.rs b/crates/nu-explore/src/nu_common/table.rs index 9a90e9058..a5bc49695 100644 --- a/crates/nu-explore/src/nu_common/table.rs +++ b/crates/nu-explore/src/nu_common/table.rs @@ -15,9 +15,10 @@ pub fn try_build_table( style_computer: &StyleComputer, value: Value, ) -> String { + let span = value.span(); match value { - Value::List { vals, span } => try_build_list(vals, ctrlc, config, span, style_computer), - Value::Record { val, span } => try_build_map(val, span, style_computer, ctrlc, config), + Value::List { vals, .. } => try_build_list(vals, ctrlc, config, span, style_computer), + Value::Record { val, .. } => try_build_map(val, span, style_computer, ctrlc, config), val if matches!(val, Value::String { .. }) => { nu_value_to_string_clean(&val, config, style_computer).0 } @@ -71,7 +72,7 @@ fn try_build_list( Ok(Some(out)) => out, Ok(None) | Err(_) => { // it means that the list is empty - nu_value_to_string(&Value::List { vals, span }, config, style_computer).0 + nu_value_to_string(&Value::list(vals, span), config, style_computer).0 } } } diff --git a/crates/nu-explore/src/nu_common/value.rs b/crates/nu-explore/src/nu_common/value.rs index 12fb26595..167cb44cd 100644 --- a/crates/nu-explore/src/nu_common/value.rs +++ b/crates/nu-explore/src/nu_common/value.rs @@ -54,10 +54,7 @@ fn collect_external_stream( let mut data = vec![]; if let Some(stdout) = stdout { let value = stdout.into_string().map_or_else( - |error| Value::Error { - error: Box::new(error), - span, - }, + |error| Value::error(error, span), |string| Value::string(string.item, span), ); @@ -66,10 +63,7 @@ fn collect_external_stream( } if let Some(stderr) = stderr { let value = stderr.into_string().map_or_else( - |error| Value::Error { - error: Box::new(error), - span, - }, + |error| Value::error(error, span), |string| Value::string(string.item, span), ); @@ -78,7 +72,7 @@ fn collect_external_stream( } if let Some(exit_code) = exit_code { let list = exit_code.collect::>(); - let val = Value::List { vals: list, span }; + let val = Value::list(list, span); columns.push(String::from("exit_code")); data.push(val); @@ -94,6 +88,7 @@ fn collect_external_stream( /// Try to build column names and a table grid. pub fn collect_input(value: Value) -> (Vec, Vec>) { + let span = value.span(); match value { Value::Record { val: record, .. } => (record.cols, vec![record.vals]), Value::List { vals, .. } => { @@ -106,23 +101,20 @@ pub fn collect_input(value: Value) -> (Vec, Vec>) { (columns, data) } - Value::String { val, span } => { + Value::String { val, .. } => { let lines = val .lines() - .map(|line| Value::String { - val: line.to_string(), - span, - }) + .map(|line| Value::string(line, span)) .map(|val| vec![val]) .collect(); (vec![String::from("")], lines) } - Value::LazyRecord { val, span } => match val.collect() { + Value::LazyRecord { val, .. } => match val.collect() { Ok(value) => collect_input(value), Err(_) => ( vec![String::from("")], - vec![vec![Value::LazyRecord { val, span }]], + vec![vec![Value::lazy_record(val, span)]], ), }, Value::Nothing { .. } => (vec![], vec![]), diff --git a/crates/nu-explore/src/views/record/mod.rs b/crates/nu-explore/src/views/record/mod.rs index cfd640aca..b7c92eb29 100644 --- a/crates/nu-explore/src/views/record/mod.rs +++ b/crates/nu-explore/src/views/record/mod.rs @@ -734,10 +734,7 @@ fn build_table_as_list(v: &RecordView) -> Value { }) .collect(); - Value::List { - vals, - span: NuSpan::unknown(), - } + Value::list(vals, NuSpan::unknown()) } fn build_table_as_record(v: &RecordView) -> Value { diff --git a/crates/nu-parser/src/eval.rs b/crates/nu-parser/src/eval.rs new file mode 100644 index 000000000..d9de4a289 --- /dev/null +++ b/crates/nu-parser/src/eval.rs @@ -0,0 +1,115 @@ +use nu_protocol::{ + ast::{Expr, Expression}, + engine::StateWorkingSet, + ParseError, Record, Span, Value, +}; + +/// Evaluate a constant value at parse time +/// +/// Based off eval_expression() in the engine +pub fn eval_constant( + working_set: &StateWorkingSet, + expr: &Expression, +) -> Result { + match &expr.expr { + Expr::Bool(b) => Ok(Value::bool(*b, expr.span)), + Expr::Int(i) => Ok(Value::int(*i, expr.span)), + Expr::Float(f) => Ok(Value::float(*f, expr.span)), + Expr::Binary(b) => Ok(Value::binary(b.clone(), expr.span)), + Expr::Filepath(path) => Ok(Value::string(path, expr.span)), + Expr::Var(var_id) => match working_set.get_variable(*var_id).const_val.as_ref() { + Some(val) => Ok(val.clone()), + None => Err(ParseError::NotAConstant(expr.span)), + }, + Expr::CellPath(cell_path) => Ok(Value::cell_path(cell_path.clone(), expr.span)), + Expr::FullCellPath(cell_path) => { + let value = eval_constant(working_set, &cell_path.head)?; + + match value.follow_cell_path(&cell_path.tail, false) { + Ok(val) => Ok(val), + // TODO: Better error conversion + Err(shell_error) => Err(ParseError::LabeledError( + "Error when following cell path".to_string(), + format!("{shell_error:?}"), + expr.span, + )), + } + } + Expr::DateTime(dt) => Ok(Value::date(*dt, expr.span)), + Expr::List(x) => { + let mut output = vec![]; + for expr in x { + output.push(eval_constant(working_set, expr)?); + } + Ok(Value::list(output, expr.span)) + } + Expr::Record(fields) => { + let mut record = Record::new(); + for (col, val) in fields { + // avoid duplicate cols. + let col_name = value_as_string(eval_constant(working_set, col)?, expr.span)?; + let pos = record.cols.iter().position(|c| c == &col_name); + match pos { + Some(index) => { + record.vals[index] = eval_constant(working_set, val)?; + } + None => { + record.push(col_name, eval_constant(working_set, val)?); + } + } + } + + Ok(Value::record(record, expr.span)) + } + Expr::Table(headers, vals) => { + let mut output_headers = vec![]; + for expr in headers { + output_headers.push(value_as_string( + eval_constant(working_set, expr)?, + expr.span, + )?); + } + + let mut output_rows = vec![]; + for val in vals { + let mut row = vec![]; + for expr in val { + row.push(eval_constant(working_set, expr)?); + } + output_rows.push(Value::record( + Record { + cols: output_headers.clone(), + vals: row, + }, + expr.span, + )); + } + Ok(Value::list(output_rows, expr.span)) + } + Expr::Keyword(_, _, expr) => eval_constant(working_set, expr), + Expr::String(s) => Ok(Value::string(s, expr.span)), + Expr::Nothing => Ok(Value::nothing(expr.span)), + Expr::ValueWithUnit(expr, unit) => { + if let Ok(Value::Int { val, .. }) = eval_constant(working_set, expr) { + unit.item.to_value(val, unit.span).map_err(|_| { + ParseError::InvalidLiteral( + "literal can not fit in unit".into(), + "literal can not fit in unit".into(), + unit.span, + ) + }) + } else { + Err(ParseError::NotAConstant(expr.span)) + } + } + _ => Err(ParseError::NotAConstant(expr.span)), + } +} + +/// Get the value as a string +pub fn value_as_string(value: Value, span: Span) -> Result { + match value { + Value::String { val, .. } => Ok(val), + _ => Err(ParseError::NotAConstant(span)), + } +} diff --git a/crates/nu-plugin/src/plugin/declaration.rs b/crates/nu-plugin/src/plugin/declaration.rs index 1059284a3..bbcacd020 100644 --- a/crates/nu-plugin/src/plugin/declaration.rs +++ b/crates/nu-plugin/src/plugin/declaration.rs @@ -84,8 +84,9 @@ impl Command for PluginDeclaration { })?; let input = input.into_value(call.head); + let span = input.span(); let input = match input { - Value::CustomValue { val, span } => { + Value::CustomValue { val, .. } => { match val.as_any().downcast_ref::() { Some(plugin_data) if plugin_data.filename == self.filename => { CallInput::Data(PluginData { @@ -145,16 +146,16 @@ impl Command for PluginDeclaration { Ok(PipelineData::Value(value.as_ref().clone(), None)) } Ok(PluginResponse::PluginData(name, plugin_data)) => Ok(PipelineData::Value( - Value::CustomValue { - val: Box::new(PluginCustomValue { + Value::custom_value( + Box::new(PluginCustomValue { name, data: plugin_data.data, filename: self.filename.clone(), shell: self.shell.clone(), source: engine_state.get_decl(call.decl_id).name().to_owned(), }), - span: plugin_data.span, - }, + plugin_data.span, + ), None, )), Ok(PluginResponse::Error(err)) => Err(err.into()), diff --git a/crates/nu-plugin/src/plugin/mod.rs b/crates/nu-plugin/src/plugin/mod.rs index 5eefb4290..6381f7629 100644 --- a/crates/nu-plugin/src/plugin/mod.rs +++ b/crates/nu-plugin/src/plugin/mod.rs @@ -214,10 +214,7 @@ pub fn get_signature( /// call: &EvaluatedCall, /// input: &Value, /// ) -> Result { -/// Ok(Value::String { -/// val: "Hello, World!".to_owned(), -/// span: call.head, -/// }) +/// Ok(Value::string("Hello, World!".to_owned(), call.head)) /// } /// } /// ``` @@ -320,9 +317,8 @@ pub fn serve_plugin(plugin: &mut impl Plugin, encoder: impl PluginEncoder) { CallInput::Value(value) => Ok(value), CallInput::Data(plugin_data) => { bincode::deserialize::>(&plugin_data.data) - .map(|custom_value| Value::CustomValue { - val: custom_value, - span: plugin_data.span, + .map(|custom_value| { + Value::custom_value(custom_value, plugin_data.span) }) .map_err(|err| ShellError::PluginFailedToDecode(err.to_string())) } @@ -334,16 +330,21 @@ pub fn serve_plugin(plugin: &mut impl Plugin, encoder: impl PluginEncoder) { }; let response = match value { - Ok(Value::CustomValue { val, span }) => match bincode::serialize(&val) { - Ok(data) => { - let name = val.value_string(); - PluginResponse::PluginData(name, PluginData { data, span }) + Ok(value) => { + let span = value.span(); + match value { + Value::CustomValue { val, .. } => match bincode::serialize(&val) { + Ok(data) => { + let name = val.value_string(); + PluginResponse::PluginData(name, PluginData { data, span }) + } + Err(err) => PluginResponse::Error( + ShellError::PluginFailedToEncode(err.to_string()).into(), + ), + }, + value => PluginResponse::Value(Box::new(value)), } - Err(err) => PluginResponse::Error( - ShellError::PluginFailedToEncode(err.to_string()).into(), - ), - }, - Ok(value) => PluginResponse::Value(Box::new(value)), + } Err(err) => PluginResponse::Error(err), }; encoder diff --git a/crates/nu-plugin/src/protocol/evaluated_call.rs b/crates/nu-plugin/src/protocol/evaluated_call.rs index b60252c03..ec2d23aca 100644 --- a/crates/nu-plugin/src/protocol/evaluated_call.rs +++ b/crates/nu-plugin/src/protocol/evaluated_call.rs @@ -115,7 +115,7 @@ impl EvaluatedCall { /// # positional: Vec::new(), /// # named: vec![( /// # Spanned { item: "foo".to_owned(), span: null_span}, - /// # Some(Value::Int { val: 123, span: null_span }) + /// # Some(Value::int(123, null_span)) /// # )], /// # }; /// let opt_foo = match call.get_flag_value("foo") { @@ -164,9 +164,9 @@ impl EvaluatedCall { /// # let call = EvaluatedCall { /// # head: null_span, /// # positional: vec![ - /// # Value::String { val: "a".to_owned(), span: null_span }, - /// # Value::String { val: "b".to_owned(), span: null_span }, - /// # Value::String { val: "c".to_owned(), span: null_span }, + /// # Value::string("a".to_owned(), null_span), + /// # Value::string("b".to_owned(), null_span), + /// # Value::string("c".to_owned(), null_span), /// # ], /// # named: vec![], /// # }; @@ -196,7 +196,7 @@ impl EvaluatedCall { /// # positional: Vec::new(), /// # named: vec![( /// # Spanned { item: "foo".to_owned(), span: null_span}, - /// # Some(Value::Int { val: 123, span: null_span }) + /// # Some(Value::int(123, null_span)) /// # )], /// # }; /// let foo = call.get_flag::("foo"); @@ -213,7 +213,7 @@ impl EvaluatedCall { /// # positional: Vec::new(), /// # named: vec![( /// # Spanned { item: "bar".to_owned(), span: null_span}, - /// # Some(Value::Int { val: 123, span: null_span }) + /// # Some(Value::int(123, null_span)) /// # )], /// # }; /// let foo = call.get_flag::("foo"); @@ -230,7 +230,7 @@ impl EvaluatedCall { /// # positional: Vec::new(), /// # named: vec![( /// # Spanned { item: "foo".to_owned(), span: null_span}, - /// # Some(Value::String { val: "abc".to_owned(), span: null_span }) + /// # Some(Value::string("abc".to_owned(), null_span)) /// # )], /// # }; /// let foo = call.get_flag::("foo"); @@ -255,10 +255,10 @@ impl EvaluatedCall { /// # let call = EvaluatedCall { /// # head: null_span, /// # positional: vec![ - /// # Value::String { val: "zero".to_owned(), span: null_span }, - /// # Value::String { val: "one".to_owned(), span: null_span }, - /// # Value::String { val: "two".to_owned(), span: null_span }, - /// # Value::String { val: "three".to_owned(), span: null_span }, + /// # Value::string("zero".to_owned(), null_span), + /// # Value::string("one".to_owned(), null_span), + /// # Value::string("two".to_owned(), null_span), + /// # Value::string("three".to_owned(), null_span), /// # ], /// # named: Vec::new(), /// # }; @@ -318,14 +318,8 @@ mod test { let call = EvaluatedCall { head: Span::new(0, 10), positional: vec![ - Value::Float { - val: 1.0, - span: Span::new(0, 10), - }, - Value::String { - val: "something".into(), - span: Span::new(0, 10), - }, + Value::float(1.0, Span::new(0, 10)), + Value::string("something", Span::new(0, 10)), ], named: vec![ ( @@ -333,10 +327,7 @@ mod test { item: "name".to_string(), span: Span::new(0, 10), }, - Some(Value::Float { - val: 1.0, - span: Span::new(0, 10), - }), + Some(Value::float(1.0, Span::new(0, 10))), ), ( Spanned { diff --git a/crates/nu-plugin/src/protocol/plugin_custom_value.rs b/crates/nu-plugin/src/protocol/plugin_custom_value.rs index 6bec15b24..995887876 100644 --- a/crates/nu-plugin/src/protocol/plugin_custom_value.rs +++ b/crates/nu-plugin/src/protocol/plugin_custom_value.rs @@ -34,10 +34,7 @@ pub struct PluginCustomValue { impl CustomValue for PluginCustomValue { fn clone_value(&self, span: nu_protocol::Span) -> nu_protocol::Value { - Value::CustomValue { - val: Box::new(self.clone()), - span, - } + Value::custom_value(Box::new(self.clone()), span) } fn value_string(&self) -> String { diff --git a/crates/nu-plugin/src/serializers/json.rs b/crates/nu-plugin/src/serializers/json.rs index 7793f03ab..b37978e48 100644 --- a/crates/nu-plugin/src/serializers/json.rs +++ b/crates/nu-plugin/src/serializers/json.rs @@ -79,32 +79,20 @@ mod tests { fn callinfo_round_trip_callinfo() { let name = "test".to_string(); - let input = Value::Bool { - val: false, - span: Span::new(1, 20), - }; + let input = Value::bool(false, Span::new(1, 20)); let call = EvaluatedCall { head: Span::new(0, 10), positional: vec![ - Value::Float { - val: 1.0, - span: Span::new(0, 10), - }, - Value::String { - val: "something".into(), - span: Span::new(0, 10), - }, + Value::float(1.0, Span::new(0, 10)), + Value::string("something", Span::new(0, 10)), ], named: vec![( Spanned { item: "name".to_string(), span: Span::new(0, 10), }, - Some(Value::Float { - val: 1.0, - span: Span::new(0, 10), - }), + Some(Value::float(1.0, Span::new(0, 10))), )], }; @@ -253,10 +241,7 @@ mod tests { #[test] fn response_round_trip_value() { - let value = Value::Int { - val: 10, - span: Span::new(2, 30), - }; + let value = Value::int(10, Span::new(2, 30)); let response = PluginResponse::Value(Box::new(value.clone())); diff --git a/crates/nu-plugin/src/serializers/msgpack.rs b/crates/nu-plugin/src/serializers/msgpack.rs index e881ce944..25dd63af5 100644 --- a/crates/nu-plugin/src/serializers/msgpack.rs +++ b/crates/nu-plugin/src/serializers/msgpack.rs @@ -78,32 +78,20 @@ mod tests { fn callinfo_round_trip_callinfo() { let name = "test".to_string(); - let input = Value::Bool { - val: false, - span: Span::new(1, 20), - }; + let input = Value::bool(false, Span::new(1, 20)); let call = EvaluatedCall { head: Span::new(0, 10), positional: vec![ - Value::Float { - val: 1.0, - span: Span::new(0, 10), - }, - Value::String { - val: "something".into(), - span: Span::new(0, 10), - }, + Value::float(1.0, Span::new(0, 10)), + Value::string("something", Span::new(0, 10)), ], named: vec![( Spanned { item: "name".to_string(), span: Span::new(0, 10), }, - Some(Value::Float { - val: 1.0, - span: Span::new(0, 10), - }), + Some(Value::float(1.0, Span::new(0, 10))), )], }; @@ -252,10 +240,7 @@ mod tests { #[test] fn response_round_trip_value() { - let value = Value::Int { - val: 10, - span: Span::new(2, 30), - }; + let value = Value::int(10, Span::new(2, 30)); let response = PluginResponse::Value(Box::new(value.clone())); diff --git a/crates/nu-protocol/src/config.rs b/crates/nu-protocol/src/config.rs index 750ed949a..9d30ab3ee 100644 --- a/crates/nu-protocol/src/config.rs +++ b/crates/nu-protocol/src/config.rs @@ -326,19 +326,19 @@ impl Value { // $env.config.ls.use_ls_colors = 2 results in an error, so // the current use_ls_colors config setting is converted to a Value::Boolean and inserted in the // record in place of the 2. - if let Value::Record { val, span } = self { + + if let Value::Record { val, .. } = self { let Record { cols, vals } = val; - let span = *span; // Because this whole algorithm removes while iterating, this must iterate in reverse. for index in (0..cols.len()).rev() { let value = &vals[index]; let key = cols[index].as_str(); + let span = vals[index].span(); match key { // Grouped options "ls" => { - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -377,14 +377,14 @@ impl Value { } } "cd" => { - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); match key2 { "abbreviations" => { - try_bool!(cols, vals, index, *span, cd_with_abbreviations) + try_bool!(cols, vals, index, span, cd_with_abbreviations) } x => { invalid_key!( @@ -410,14 +410,14 @@ impl Value { } } "rm" => { - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); match key2 { "always_trash" => { - try_bool!(cols, vals, index, *span, rm_always_trash) + try_bool!(cols, vals, index, span, rm_always_trash) } x => { invalid_key!( @@ -453,9 +453,8 @@ impl Value { ) }; } - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -525,12 +524,9 @@ impl Value { macro_rules! reconstruct_external_completer { ($span: expr) => { if let Some(block) = config.external_completer { - Value::Block { - val: block, - span: $span, - } + Value::block(block, $span) } else { - Value::Nothing { span: $span } + Value::nothing($span) } }; } @@ -546,9 +542,8 @@ impl Value { ) }; } - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -597,9 +592,8 @@ impl Value { ) } "external" => { - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key3 = cols[index].as_str(); @@ -700,9 +694,8 @@ impl Value { ) }; } - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -905,7 +898,7 @@ impl Value { }, None => record! { "methodology" => Value::string("truncating", $span), - "truncating_suffix" => Value::Nothing { span: $span }, + "truncating_suffix" => Value::nothing($span), }, }, $span, @@ -913,9 +906,8 @@ impl Value { } }; } - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -1046,9 +1038,8 @@ impl Value { } } "filesize" => { - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -1140,15 +1131,15 @@ impl Value { } else { invalid!(Some(span), "should be a string"); // Reconstruct - vals[index] = Value::String { - val: match config.footer_mode { + vals[index] = Value::string( + match config.footer_mode { FooterMode::Auto => "auto".into(), FooterMode::Never => "never".into(), FooterMode::Always => "always".into(), FooterMode::RowCount(number) => number.to_string(), }, span, - }; + ); } } "float_precision" => { @@ -1192,8 +1183,7 @@ impl Value { invalid!(Some(span), "should be a valid list of menus"); errors.push(e); // Reconstruct - vals[index] = Value::List { - vals: config + vals[index] = Value::list(config .menus .iter() .map( @@ -1220,7 +1210,7 @@ impl Value { ) .collect(), span, - } + ) } }, // Keybindings @@ -1230,8 +1220,8 @@ impl Value { invalid!(Some(span), "should be a valid keybindings list"); errors.push(e); // Reconstruct - vals[index] = Value::List { - vals: config + vals[index] = Value::list( + config .keybindings .iter() .map( @@ -1254,7 +1244,7 @@ impl Value { ) .collect(), span, - } + ) } }, // Hooks @@ -1281,9 +1271,8 @@ impl Value { } }, "datetime_format" => { - if let Value::Record { val, span } = &mut vals[index] { + if let Value::Record { val, .. } = &mut vals[index] { let Record { cols, vals } = val; - let span = *span; for index in (0..cols.len()).rev() { let value = &vals[index]; let key2 = cols[index].as_str(); @@ -1475,8 +1464,9 @@ fn create_map(value: &Value) -> Result, ShellError> { // Parse the hooks to find the blocks to run when the hooks fire fn create_hooks(value: &Value) -> Result { + let span = value.span(); match value { - Value::Record { val, span } => { + Value::Record { val, .. } => { let mut hooks = Hooks::new(); for (col, val) in val { @@ -1491,7 +1481,7 @@ fn create_hooks(value: &Value) -> Result { "'pre_prompt', 'pre_execution', 'env_change', 'display_output', 'command_not_found'" .to_string(), x.to_string(), - *span, + span, )); } } @@ -1499,19 +1489,19 @@ fn create_hooks(value: &Value) -> Result { Ok(hooks) } - v => Err(ShellError::UnsupportedConfigValue( + _ => Err(ShellError::UnsupportedConfigValue( "record for 'hooks' config".into(), "non-record value".into(), - v.span(), + span, )), } } // Parses the config object to extract the strings that will compose a keybinding for reedline fn create_keybindings(value: &Value) -> Result, ShellError> { + let span = value.span(); match value { - Value::Record { val, span } => { - let span = *span; + Value::Record { val, .. } => { // Finding the modifier value in the record let modifier = extract_value("modifier", val, span)?.clone(); let keycode = extract_value("keycode", val, span)?.clone(); @@ -1547,9 +1537,9 @@ fn create_keybindings(value: &Value) -> Result, ShellError // Parses the config object to extract the strings that will compose a keybinding for reedline pub fn create_menus(value: &Value) -> Result, ShellError> { + let span = value.span(); match value { - Value::Record { val, span } => { - let span = *span; + Value::Record { val, .. } => { // Finding the modifier value in the record let name = extract_value("name", val, span)?.clone(); let marker = extract_value("marker", val, span)?.clone(); @@ -1561,7 +1551,7 @@ pub fn create_menus(value: &Value) -> Result, ShellError> { // Source is an optional value let source = match extract_value("source", val, span) { Ok(source) => source.clone(), - Err(_) => Value::Nothing { span }, + Err(_) => Value::nothing(span), }; let menu = ParsedMenu { diff --git a/crates/nu-protocol/src/engine/pattern_match.rs b/crates/nu-protocol/src/engine/pattern_match.rs index 307a6b2fb..36419a0fc 100644 --- a/crates/nu-protocol/src/engine/pattern_match.rs +++ b/crates/nu-protocol/src/engine/pattern_match.rs @@ -75,13 +75,7 @@ impl Matcher for Pattern { } Pattern::Rest(var_id) => { let rest_vals = vals[val_idx..].to_vec(); - matches.push(( - *var_id, - Value::List { - vals: rest_vals, - span: pattern.span, - }, - )); + matches.push((*var_id, Value::list(rest_vals, pattern.span))); break; } _ => { diff --git a/crates/nu-protocol/src/eval_const.rs b/crates/nu-protocol/src/eval_const.rs index 01bb5a98c..6cb8e13e5 100644 --- a/crates/nu-protocol/src/eval_const.rs +++ b/crates/nu-protocol/src/eval_const.rs @@ -244,22 +244,13 @@ pub fn eval_constant( Expr::Bool(b) => Ok(Value::bool(*b, expr.span)), Expr::Int(i) => Ok(Value::int(*i, expr.span)), Expr::Float(f) => Ok(Value::float(*f, expr.span)), - Expr::Binary(b) => Ok(Value::Binary { - val: b.clone(), - span: expr.span, - }), - Expr::Filepath(path) => Ok(Value::String { - val: path.clone(), - span: expr.span, - }), + Expr::Binary(b) => Ok(Value::binary(b.clone(), expr.span)), + Expr::Filepath(path) => Ok(Value::string(path.clone(), expr.span)), Expr::Var(var_id) => match working_set.get_variable(*var_id).const_val.as_ref() { Some(val) => Ok(val.clone()), None => Err(ShellError::NotAConstant(expr.span)), }, - Expr::CellPath(cell_path) => Ok(Value::CellPath { - val: cell_path.clone(), - span: expr.span, - }), + Expr::CellPath(cell_path) => Ok(Value::cell_path(cell_path.clone(), expr.span)), Expr::FullCellPath(cell_path) => { let value = eval_constant(working_set, &cell_path.head)?; @@ -275,19 +266,13 @@ pub fn eval_constant( )), } } - Expr::DateTime(dt) => Ok(Value::Date { - val: *dt, - span: expr.span, - }), + Expr::DateTime(dt) => Ok(Value::date(*dt, expr.span)), Expr::List(x) => { let mut output = vec![]; for expr in x { output.push(eval_constant(working_set, expr)?); } - Ok(Value::List { - vals: output, - span: expr.span, - }) + Ok(Value::list(output, expr.span)) } Expr::Record(fields) => { let mut record = Record::new(); @@ -330,17 +315,11 @@ pub fn eval_constant( expr.span, )); } - Ok(Value::List { - vals: output_rows, - span: expr.span, - }) + Ok(Value::list(output_rows, expr.span)) } Expr::Keyword(_, _, expr) => eval_constant(working_set, expr), - Expr::String(s) => Ok(Value::String { - val: s.clone(), - span: expr.span, - }), - Expr::Nothing => Ok(Value::Nothing { span: expr.span }), + Expr::String(s) => Ok(Value::string(s.clone(), expr.span)), + Expr::Nothing => Ok(Value::nothing(expr.span)), Expr::ValueWithUnit(expr, unit) => { if let Ok(Value::Int { val, .. }) = eval_constant(working_set, expr) { unit.item.to_value(val, unit.span) diff --git a/crates/nu-protocol/src/pipeline_data.rs b/crates/nu-protocol/src/pipeline_data.rs index e127475e5..f9b1c1220 100644 --- a/crates/nu-protocol/src/pipeline_data.rs +++ b/crates/nu-protocol/src/pipeline_data.rs @@ -69,7 +69,7 @@ pub enum DataSource { impl PipelineData { pub fn new_with_metadata(metadata: Option>, span: Span) -> PipelineData { - PipelineData::Value(Value::Nothing { span }, metadata) + PipelineData::Value(Value::nothing(span), metadata) } /// create a `PipelineData::ExternalStream` with proper exit_code @@ -133,10 +133,10 @@ impl PipelineData { PipelineData::Empty => Value::nothing(span), PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span), PipelineData::Value(v, ..) => v.with_span(span), - PipelineData::ListStream(s, ..) => Value::List { - vals: s.collect(), + PipelineData::ListStream(s, ..) => Value::list( + s.collect(), span, // FIXME? - }, + ), PipelineData::ExternalStream { stdout: None, exit_code, @@ -146,7 +146,7 @@ impl PipelineData { if let Some(exit_code) = exit_code { let _: Vec<_> = exit_code.into_iter().collect(); } - Value::Nothing { span } + Value::nothing(span) } PipelineData::ExternalStream { stdout: Some(mut s), @@ -162,10 +162,7 @@ impl PipelineData { items.push(val); } Err(e) => { - return Value::Error { - error: Box::new(e), - span, - }; + return Value::error(e, span); } } } @@ -185,38 +182,30 @@ impl PipelineData { output.extend(item); } Err(err) => { - return Value::Error { - error: Box::new(err), - span, - }; + return Value::error(err, span); } } } - Value::Binary { - val: output, - span, // FIXME? - } + Value::binary( + output, span, // FIXME? + ) } else { let mut output = String::new(); for item in items { match item.as_string() { Ok(s) => output.push_str(&s), Err(err) => { - return Value::Error { - error: Box::new(err), - span, - }; + return Value::error(err, span); } } } if trim_end_newline { output.truncate(output.trim_end_matches(LINE_ENDING_PATTERN).len()) } - Value::String { - val: output, - span, // FIXME? - } + Value::string( + output, span, // FIXME? + ) } } } @@ -288,7 +277,7 @@ impl PipelineData { }, metadata, ))), - Value::Binary { val, span } => Ok(PipelineIterator(PipelineData::ListStream( + Value::Binary { val, .. } => Ok(PipelineIterator(PipelineData::ListStream( ListStream { stream: Box::new(val.into_iter().map(move |x| Value::int(x as i64, span))), ctrlc: None, @@ -368,7 +357,7 @@ impl PipelineData { ) -> Result<(String, Span, Option>), ShellError> { match self { PipelineData::Empty => Ok((String::new(), span, None)), - PipelineData::Value(Value::String { val, span }, metadata) => Ok((val, span, metadata)), + PipelineData::Value(Value::String { val, .. }, metadata) => Ok((val, span, metadata)), PipelineData::Value(val, _) => Err(ShellError::TypeMismatch { err_message: "string".into(), span: val.span(), @@ -400,11 +389,9 @@ impl PipelineData { ) -> Result { match self { // FIXME: there are probably better ways of doing this - PipelineData::ListStream(stream, ..) => Value::List { - vals: stream.collect(), - span: head, + PipelineData::ListStream(stream, ..) => { + Value::list(stream.collect(), head).follow_cell_path(cell_path, insensitive) } - .follow_cell_path(cell_path, insensitive), PipelineData::Value(v, ..) => v.follow_cell_path(cell_path, insensitive), _ => Err(ShellError::IOError("can't follow stream paths".into())), } @@ -418,11 +405,9 @@ impl PipelineData { ) -> Result<(), ShellError> { match self { // FIXME: there are probably better ways of doing this - PipelineData::ListStream(stream, ..) => Value::List { - vals: stream.collect(), - span: head, + PipelineData::ListStream(stream, ..) => { + Value::list(stream.collect(), head).upsert_cell_path(cell_path, callback) } - .upsert_cell_path(cell_path, callback), PipelineData::Value(v, ..) => v.upsert_cell_path(cell_path, callback), _ => Ok(()), } @@ -456,17 +441,9 @@ impl PipelineData { if trim_end_newline { st.truncate(st.trim_end_matches(LINE_ENDING_PATTERN).len()); } - Ok(f(Value::String { - val: st, - span: collected.span, - }) - .into_pipeline_data()) + Ok(f(Value::string(st, collected.span)).into_pipeline_data()) } else { - Ok(f(Value::Binary { - val: collected.item, - span: collected.span, - }) - .into_pipeline_data()) + Ok(f(Value::binary(collected.item, collected.span)).into_pipeline_data()) } } @@ -513,19 +490,13 @@ impl PipelineData { if trim_end_newline { st.truncate(st.trim_end_matches(LINE_ENDING_PATTERN).len()) } - Ok(f(Value::String { - val: st, - span: collected.span, - }) - .into_iter() - .into_pipeline_data(ctrlc)) + Ok(f(Value::string(st, collected.span)) + .into_iter() + .into_pipeline_data(ctrlc)) } else { - Ok(f(Value::Binary { - val: collected.item, - span: collected.span, - }) - .into_iter() - .into_pipeline_data(ctrlc)) + Ok(f(Value::binary(collected.item, collected.span)) + .into_iter() + .into_pipeline_data(ctrlc)) } } PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val @@ -563,10 +534,7 @@ impl PipelineData { if trim_end_newline { st.truncate(st.trim_end_matches(LINE_ENDING_PATTERN).len()) } - let v = Value::String { - val: st, - span: collected.span, - }; + let v = Value::string(st, collected.span); if f(&v) { Ok(v.into_pipeline_data()) @@ -574,10 +542,7 @@ impl PipelineData { Ok(PipelineData::new_with_metadata(None, collected.span)) } } else { - let v = Value::Binary { - val: collected.item, - span: collected.span, - }; + let v = Value::binary(collected.item, collected.span); if f(&v) { Ok(v.into_pipeline_data()) @@ -594,7 +559,7 @@ impl PipelineData { if f(&v) { Ok(v.into_pipeline_data()) } else { - Ok(Value::Nothing { span: v.span() }.into_pipeline_data()) + Ok(Value::nothing(v.span()).into_pipeline_data()) } } } @@ -691,43 +656,43 @@ impl PipelineData { /// `1..3 | to XX -> [1,2,3]` pub fn try_expand_range(self) -> Result { let input = match self { - PipelineData::Value(Value::Range { val, span }, ..) => { - match (&val.to, &val.from) { - (Value::Float { val, .. }, _) | (_, Value::Float { val, .. }) => { - if *val == f64::INFINITY || *val == f64::NEG_INFINITY { - return Err(ShellError::GenericError( - "Cannot create range".into(), - "Infinity is not allowed when converting to json".into(), - Some(span), - Some("Consider removing infinity".into()), - vec![], - )); + PipelineData::Value(v, metadata) => match v { + Value::Range { val, .. } => { + let span = val.to.span(); + match (&val.to, &val.from) { + (Value::Float { val, .. }, _) | (_, Value::Float { val, .. }) => { + if *val == f64::INFINITY || *val == f64::NEG_INFINITY { + return Err(ShellError::GenericError( + "Cannot create range".into(), + "Infinity is not allowed when converting to json".into(), + Some(span), + Some("Consider removing infinity".into()), + vec![], + )); + } } - } - (Value::Int { val, span }, _) => { - if *val == i64::MAX || *val == i64::MIN { - return Err(ShellError::GenericError( - "Cannot create range".into(), - "Unbounded ranges are not allowed when converting to json".into(), - Some(*span), - Some( - "Consider using ranges with valid start and end point.".into(), - ), - vec![], - )); + (Value::Int { val, .. }, _) => { + if *val == i64::MAX || *val == i64::MIN { + return Err(ShellError::GenericError( + "Cannot create range".into(), + "Unbounded ranges are not allowed when converting to json" + .into(), + Some(span), + Some( + "Consider using ranges with valid start and end point." + .into(), + ), + vec![], + )); + } } + _ => (), } - _ => (), + let range_values: Vec = val.into_range_iter(None)?.collect(); + PipelineData::Value(Value::list(range_values, span), None) } - let range_values: Vec = val.into_range_iter(None)?.collect(); - PipelineData::Value( - Value::List { - vals: range_values, - span, - }, - None, - ) - } + x => PipelineData::Value(x, metadata), + }, _ => self, }; Ok(input) @@ -847,34 +812,33 @@ impl IntoIterator for PipelineData { fn into_iter(self) -> Self::IntoIter { match self { - PipelineData::Value(Value::List { vals, .. }, metadata) => { - PipelineIterator(PipelineData::ListStream( - ListStream { - stream: Box::new(vals.into_iter()), - ctrlc: None, + PipelineData::Value(v, metadata) => { + let span = v.span(); + match v { + Value::List { vals, .. } => PipelineIterator(PipelineData::ListStream( + ListStream { + stream: Box::new(vals.into_iter()), + ctrlc: None, + }, + metadata, + )), + Value::Range { val, .. } => match val.into_range_iter(None) { + Ok(iter) => PipelineIterator(PipelineData::ListStream( + ListStream { + stream: Box::new(iter), + ctrlc: None, + }, + metadata, + )), + Err(error) => PipelineIterator(PipelineData::ListStream( + ListStream { + stream: Box::new(std::iter::once(Value::error(error, span))), + ctrlc: None, + }, + metadata, + )), }, - metadata, - )) - } - PipelineData::Value(Value::Range { val, span }, metadata) => { - match val.into_range_iter(None) { - Ok(iter) => PipelineIterator(PipelineData::ListStream( - ListStream { - stream: Box::new(iter), - ctrlc: None, - }, - metadata, - )), - Err(error) => PipelineIterator(PipelineData::ListStream( - ListStream { - stream: Box::new(std::iter::once(Value::Error { - error: Box::new(error), - span, - })), - ctrlc: None, - }, - metadata, - )), + x => PipelineIterator(PipelineData::Value(x, metadata)), } } x => PipelineIterator(x), @@ -941,10 +905,10 @@ impl Iterator for PipelineIterator { .. } => stream.next().map(|x| match x { Ok(x) => x, - Err(err) => Value::Error { - error: Box::new(err), - span: Span::unknown(), //FIXME: unclear where this span should come from - }, + Err(err) => Value::error( + err, + Span::unknown(), //FIXME: unclear where this span should come from + ), }), } } diff --git a/crates/nu-protocol/src/value/from_value.rs b/crates/nu-protocol/src/value/from_value.rs index 6759efb39..aafbee827 100644 --- a/crates/nu-protocol/src/value/from_value.rs +++ b/crates/nu-protocol/src/value/from_value.rs @@ -19,19 +19,11 @@ impl FromValue for Value { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Int { val, span } => Ok(Spanned { - item: *val, - span: *span, - }), - Value::Filesize { val, span } => Ok(Spanned { - item: *val, - span: *span, - }), - Value::Duration { val, span } => Ok(Spanned { - item: *val, - span: *span, - }), + Value::Int { val, .. } => Ok(Spanned { item: *val, span }), + Value::Filesize { val, .. } => Ok(Spanned { item: *val, span }), + Value::Duration { val, .. } => Ok(Spanned { item: *val, span }), v => Err(ShellError::CantConvert { to_type: "integer".into(), @@ -62,15 +54,13 @@ impl FromValue for i64 { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Int { val, span } => Ok(Spanned { + Value::Int { val, .. } => Ok(Spanned { item: *val as f64, - span: *span, - }), - Value::Float { val, span } => Ok(Spanned { - item: *val, - span: *span, + span, }), + Value::Float { val, .. } => Ok(Spanned { item: *val, span }), v => Err(ShellError::CantConvert { to_type: "float".into(), @@ -99,34 +89,35 @@ impl FromValue for f64 { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Int { val, span } => { + Value::Int { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(Spanned { item: *val as usize, - span: *span, + span, }) } } - Value::Filesize { val, span } => { + Value::Filesize { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(Spanned { item: *val as usize, - span: *span, + span, }) } } - Value::Duration { val, span } => { + Value::Duration { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(Spanned { item: *val as usize, - span: *span, + span, }) } } @@ -143,24 +134,25 @@ impl FromValue for Spanned { impl FromValue for usize { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Int { val, span } => { + Value::Int { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(*val as usize) } } - Value::Filesize { val, span } => { + Value::Filesize { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(*val as usize) } } - Value::Duration { val, span } => { + Value::Duration { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(*val as usize) } @@ -244,17 +236,20 @@ impl FromValue for Vec> { match v { Value::List { vals, .. } => vals .iter() - .map(|val| match val { - Value::String { val, span } => Ok(Spanned { - item: val.clone(), - span: *span, - }), - c => Err(ShellError::CantConvert { - to_type: "string".into(), - from_type: c.get_type().to_string(), - span: c.span(), - help: None, - }), + .map(|val| { + let val_span = val.span(); + match val { + Value::String { val, .. } => Ok(Spanned { + item: val.clone(), + span: val_span, + }), + c => Err(ShellError::CantConvert { + to_type: "string".into(), + from_type: c.get_type().to_string(), + span: c.span(), + help: None, + }), + } }) .collect::>, ShellError>>(), v => Err(ShellError::CantConvert { @@ -304,14 +299,14 @@ impl FromValue for CellPath { optional: false, }], }), - Value::Int { val, span } => { + Value::Int { val, .. } => { if val.is_negative() { - Err(ShellError::NeedsPositiveValue(*span)) + Err(ShellError::NeedsPositiveValue(span)) } else { Ok(CellPath { members: vec![PathMember::Int { val: *val as usize, - span: *span, + span, optional: false, }], }) @@ -343,11 +338,9 @@ impl FromValue for bool { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Bool { val, span } => Ok(Spanned { - item: *val, - span: *span, - }), + Value::Bool { val, .. } => Ok(Spanned { item: *val, span }), v => Err(ShellError::CantConvert { to_type: "bool".into(), from_type: v.get_type().to_string(), @@ -374,11 +367,9 @@ impl FromValue for DateTime { impl FromValue for Spanned> { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Date { val, span } => Ok(Spanned { - item: *val, - span: *span, - }), + Value::Date { val, .. } => Ok(Spanned { item: *val, span }), v => Err(ShellError::CantConvert { to_type: "date".into(), from_type: v.get_type().to_string(), @@ -405,10 +396,11 @@ impl FromValue for Range { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Range { val, span } => Ok(Spanned { + Value::Range { val, .. } => Ok(Spanned { item: (**val).clone(), - span: *span, + span, }), v => Err(ShellError::CantConvert { to_type: "range".into(), @@ -437,14 +429,15 @@ impl FromValue for Vec { impl FromValue for Spanned> { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Binary { val, span } => Ok(Spanned { + Value::Binary { val, .. } => Ok(Spanned { item: val.clone(), - span: *span, + span, }), - Value::String { val, span } => Ok(Spanned { + Value::String { val, .. } => Ok(Spanned { item: val.bytes().collect(), - span: *span, + span, }), v => Err(ShellError::CantConvert { to_type: "binary data".into(), @@ -458,11 +451,12 @@ impl FromValue for Spanned> { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::String { val, span } => Ok(Spanned { + Value::String { val, .. } => Ok(Spanned { item: PathBuf::from_str(val) - .map_err(|err| ShellError::FileNotFoundCustom(err.to_string(), *span))?, - span: *span, + .map_err(|err| ShellError::FileNotFoundCustom(err.to_string(), span))?, + span, }), v => Err(ShellError::CantConvert { to_type: "range".into(), @@ -540,17 +534,14 @@ impl FromValue for Block { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::Closure { - val, - captures, - span, - } => Ok(Spanned { + Value::Closure { val, captures, .. } => Ok(Spanned { item: Closure { block_id: *val, captures: captures.clone(), }, - span: *span, + span, }), v => Err(ShellError::CantConvert { to_type: "Closure".into(), @@ -564,10 +555,11 @@ impl FromValue for Spanned { impl FromValue for Spanned { fn from_value(v: &Value) -> Result { + let span = v.span(); match v { - Value::MatchPattern { val, span } => Ok(Spanned { + Value::MatchPattern { val, .. } => Ok(Spanned { item: *val.clone(), - span: *span, + span, }), v => Err(ShellError::CantConvert { to_type: "Match pattern".into(), diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 2b80556d5..ae78b6406 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -44,149 +44,195 @@ pub use unit::*; pub enum Value { Bool { val: bool, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Int { val: i64, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Float { val: f64, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Filesize { val: i64, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Duration { val: i64, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Date { val: DateTime, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Range { val: Box, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, String { val: String, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Record { val: Record, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, List { vals: Vec, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Block { val: BlockId, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Closure { val: BlockId, captures: HashMap, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Nothing { - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Error { error: Box, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, Binary { val: Vec, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, CellPath { val: CellPath, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, #[serde(skip_serializing)] CustomValue { val: Box, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, #[serde(skip)] LazyRecord { val: Box LazyRecord<'a>>, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, MatchPattern { val: Box, - span: Span, + // note: spans are being refactored out of Value + // please use .span() instead of matching this span value + internal_span: Span, }, } impl Clone for Value { fn clone(&self) -> Self { match self { - Value::Bool { val, span } => Value::bool(*val, *span), - Value::Int { val, span } => Value::int(*val, *span), - Value::Filesize { val, span } => Value::Filesize { + Value::Bool { val, internal_span } => Value::bool(*val, *internal_span), + Value::Int { val, internal_span } => Value::int(*val, *internal_span), + Value::Filesize { val, internal_span } => Value::Filesize { val: *val, - span: *span, + internal_span: *internal_span, }, - Value::Duration { val, span } => Value::Duration { + Value::Duration { val, internal_span } => Value::Duration { val: *val, - span: *span, + internal_span: *internal_span, }, - Value::Date { val, span } => Value::Date { + Value::Date { val, internal_span } => Value::Date { val: *val, - span: *span, + internal_span: *internal_span, }, - Value::Range { val, span } => Value::Range { + Value::Range { val, internal_span } => Value::Range { val: val.clone(), - span: *span, + internal_span: *internal_span, }, - Value::Float { val, span } => Value::float(*val, *span), - Value::String { val, span } => Value::String { + Value::Float { val, internal_span } => Value::float(*val, *internal_span), + Value::String { val, internal_span } => Value::String { val: val.clone(), - span: *span, + internal_span: *internal_span, }, - Value::Record { val, span } => Value::Record { + Value::Record { val, internal_span } => Value::Record { val: val.clone(), - span: *span, + internal_span: *internal_span, }, - Value::LazyRecord { val, span } => val.clone_value(*span), - Value::List { vals, span } => Value::List { + Value::LazyRecord { val, internal_span } => val.clone_value(*internal_span), + Value::List { + vals, + internal_span, + } => Value::List { vals: vals.clone(), - span: *span, + internal_span: *internal_span, }, - Value::Block { val, span } => Value::Block { + Value::Block { val, internal_span } => Value::Block { val: *val, - span: *span, + internal_span: *internal_span, }, Value::Closure { val, captures, - span, + internal_span, } => Value::Closure { val: *val, captures: captures.clone(), - span: *span, + internal_span: *internal_span, }, - Value::Nothing { span } => Value::Nothing { span: *span }, - Value::Error { error, span } => Value::Error { + Value::Nothing { internal_span } => Value::Nothing { + internal_span: *internal_span, + }, + Value::Error { + error, + internal_span, + } => Value::Error { error: error.clone(), - span: *span, + internal_span: *internal_span, }, - Value::Binary { val, span } => Value::Binary { + Value::Binary { val, internal_span } => Value::Binary { val: val.clone(), - span: *span, + internal_span: *internal_span, }, - Value::CellPath { val, span } => Value::CellPath { + Value::CellPath { val, internal_span } => Value::CellPath { val: val.clone(), - span: *span, + internal_span: *internal_span, }, - Value::CustomValue { val, span } => val.clone_value(*span), - Value::MatchPattern { val, span } => Value::MatchPattern { + Value::CustomValue { val, internal_span } => val.clone_value(*internal_span), + Value::MatchPattern { val, internal_span } => Value::MatchPattern { val: val.clone(), - span: *span, + internal_span: *internal_span, }, } } @@ -306,15 +352,16 @@ impl Value { } pub fn as_spanned_string(&self) -> Result, ShellError> { + let span = self.span(); match self { - Value::String { val, span } => Ok(Spanned { + Value::String { val, .. } => Ok(Spanned { item: val.to_string(), - span: *span, + span, }), - Value::Binary { val, span } => Ok(match std::str::from_utf8(val) { + Value::Binary { val, .. } => Ok(match std::str::from_utf8(val) { Ok(s) => Spanned { item: s.to_string(), - span: *span, + span, }, Err(_) => { return Err(ShellError::CantConvert { @@ -335,21 +382,23 @@ impl Value { } pub fn as_char(&self) -> Result { + let span = self.span(); + match self { - Value::String { val, span } => { + Value::String { val, .. } => { let mut chars = val.chars(); match (chars.next(), chars.next()) { (Some(c), None) => Ok(c), _ => Err(ShellError::MissingParameter { param_name: "single character separator".into(), - span: *span, + span, }), } } x => Err(ShellError::CantConvert { to_type: "char".into(), from_type: x.get_type().to_string(), - span: self.span(), + span, help: None, }), } @@ -480,49 +529,49 @@ impl Value { /// Get the span for the current value pub fn span(&self) -> Span { match self { - Value::Bool { span, .. } - | Value::Int { span, .. } - | Value::Float { span, .. } - | Value::Filesize { span, .. } - | Value::Duration { span, .. } - | Value::Date { span, .. } - | Value::Range { span, .. } - | Value::String { span, .. } - | Value::Record { span, .. } - | Value::List { span, .. } - | Value::Block { span, .. } - | Value::Closure { span, .. } - | Value::Nothing { span, .. } - | Value::Binary { span, .. } - | Value::CellPath { span, .. } - | Value::CustomValue { span, .. } - | Value::LazyRecord { span, .. } - | Value::MatchPattern { span, .. } - | Value::Error { span, .. } => *span, + Value::Bool { internal_span, .. } + | Value::Int { internal_span, .. } + | Value::Float { internal_span, .. } + | Value::Filesize { internal_span, .. } + | Value::Duration { internal_span, .. } + | Value::Date { internal_span, .. } + | Value::Range { internal_span, .. } + | Value::String { internal_span, .. } + | Value::Record { internal_span, .. } + | Value::List { internal_span, .. } + | Value::Block { internal_span, .. } + | Value::Closure { internal_span, .. } + | Value::Nothing { internal_span, .. } + | Value::Binary { internal_span, .. } + | Value::CellPath { internal_span, .. } + | Value::CustomValue { internal_span, .. } + | Value::LazyRecord { internal_span, .. } + | Value::MatchPattern { internal_span, .. } + | Value::Error { internal_span, .. } => *internal_span, } } /// Update the value with a new span pub fn with_span(mut self, new_span: Span) -> Value { match &mut self { - Value::Bool { span, .. } - | Value::Int { span, .. } - | Value::Float { span, .. } - | Value::Filesize { span, .. } - | Value::Duration { span, .. } - | Value::Date { span, .. } - | Value::Range { span, .. } - | Value::String { span, .. } - | Value::Record { span, .. } - | Value::LazyRecord { span, .. } - | Value::List { span, .. } - | Value::Closure { span, .. } - | Value::Block { span, .. } - | Value::Nothing { span, .. } - | Value::Binary { span, .. } - | Value::CellPath { span, .. } - | Value::CustomValue { span, .. } - | Value::MatchPattern { span, .. } => *span = new_span, + Value::Bool { internal_span, .. } + | Value::Int { internal_span, .. } + | Value::Float { internal_span, .. } + | Value::Filesize { internal_span, .. } + | Value::Duration { internal_span, .. } + | Value::Date { internal_span, .. } + | Value::Range { internal_span, .. } + | Value::String { internal_span, .. } + | Value::Record { internal_span, .. } + | Value::LazyRecord { internal_span, .. } + | Value::List { internal_span, .. } + | Value::Closure { internal_span, .. } + | Value::Block { internal_span, .. } + | Value::Nothing { internal_span, .. } + | Value::Binary { internal_span, .. } + | Value::CellPath { internal_span, .. } + | Value::CustomValue { internal_span, .. } + | Value::MatchPattern { internal_span, .. } => *internal_span = new_span, Value::Error { .. } => (), } @@ -584,28 +633,26 @@ impl Value { } pub fn get_data_by_key(&self, name: &str) -> Option { + let span = self.span(); match self { Value::Record { val, .. } => val .iter() .find(|(col, _)| col == &name) .map(|(_, val)| val.clone()), - Value::List { vals, span } => { + Value::List { vals, .. } => { let mut out = vec![]; for item in vals { match item { Value::Record { .. } => match item.get_data_by_key(name) { Some(v) => out.push(v), - None => out.push(Value::nothing(*span)), + None => out.push(Value::nothing(span)), }, - _ => out.push(Value::nothing(*span)), + _ => out.push(Value::nothing(span)), } } if !out.is_empty() { - Some(Value::List { - vals: out, - span: *span, - }) + Some(Value::list(out, span)) } else { None } @@ -629,6 +676,8 @@ impl Value { /// Convert Value into string. Note that Streams will be consumed. pub fn into_string(&self, separator: &str, config: &Config) -> String { + let span = self.span(); + match self { Value::Bool { val, .. } => val.to_string(), Value::Int { val, .. } => val.to_string(), @@ -672,12 +721,12 @@ impl Value { .collect::>() .join(separator) ), - Value::LazyRecord { val, span } => { + Value::LazyRecord { val, .. } => { let collected = match val.collect() { Ok(val) => val, Err(error) => Value::Error { error: Box::new(error), - span: *span, + internal_span: span, }, }; collected.into_string(separator, config) @@ -971,72 +1020,88 @@ impl Value { val: column_name, span: origin_span, optional, - } => match &mut current { - Value::Record { val, span } => { - let span = *span; + } => { + let span = current.span(); - // Make reverse iterate to avoid duplicate column leads to first value, actually last value is expected. - if let Some(found) = val.iter().rev().find(|x| { - if insensitive { - x.0.to_lowercase() == column_name.to_lowercase() + match &mut current { + Value::Record { val, .. } => { + // Make reverse iterate to avoid duplicate column leads to first value, actually last value is expected. + if let Some(found) = val.iter().rev().find(|x| { + if insensitive { + x.0.to_lowercase() == column_name.to_lowercase() + } else { + x.0 == column_name + } + }) { + current = found.1.clone(); + } else if *optional { + return Ok(Value::nothing(*origin_span)); // short-circuit } else { - x.0 == column_name - } - }) { - current = found.1.clone(); - } else if *optional { - return Ok(Value::nothing(*origin_span)); // short-circuit - } else { - if from_user_input { - if let Some(suggestion) = did_you_mean(&val.cols, column_name) { - return Err(ShellError::DidYouMean(suggestion, *origin_span)); + if from_user_input { + if let Some(suggestion) = did_you_mean(&val.cols, column_name) { + return Err(ShellError::DidYouMean( + suggestion, + *origin_span, + )); + } } + return Err(ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: span, + }); } - return Err(ShellError::CantFindColumn { - col_name: column_name.to_string(), - span: *origin_span, - src_span: span, - }); } - } - Value::LazyRecord { val, span } => { - let columns = val.column_names(); + Value::LazyRecord { val, .. } => { + let columns = val.column_names(); - if columns.contains(&column_name.as_str()) { - current = val.get_column_value(column_name)?; - } else if *optional { - return Ok(Value::nothing(*origin_span)); // short-circuit - } else { - if from_user_input { - if let Some(suggestion) = did_you_mean(&columns, column_name) { - return Err(ShellError::DidYouMean(suggestion, *origin_span)); + if columns.contains(&column_name.as_str()) { + current = val.get_column_value(column_name)?; + } else if *optional { + return Ok(Value::nothing(*origin_span)); // short-circuit + } else { + if from_user_input { + if let Some(suggestion) = did_you_mean(&columns, column_name) { + return Err(ShellError::DidYouMean( + suggestion, + *origin_span, + )); + } } + return Err(ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: span, + }); } - return Err(ShellError::CantFindColumn { - col_name: column_name.to_string(), - span: *origin_span, - src_span: *span, - }); } - } - // String access of Lists always means Table access. - // Create a List which contains each matching value for contained - // records in the source list. - Value::List { vals, span } => { - // TODO: this should stream instead of collecting - let mut output = vec![]; - for val in vals { - // only look in records; this avoids unintentionally recursing into deeply nested tables - if matches!(val, Value::Record { .. }) { - if let Ok(result) = val.clone().follow_cell_path( - &[PathMember::String { - val: column_name.clone(), - span: *origin_span, - optional: *optional, - }], - insensitive, - ) { - output.push(result); + // String access of Lists always means Table access. + // Create a List which contains each matching value for contained + // records in the source list. + Value::List { vals, .. } => { + // TODO: this should stream instead of collecting + let mut output = vec![]; + for val in vals { + // only look in records; this avoids unintentionally recursing into deeply nested tables + if matches!(val, Value::Record { .. }) { + if let Ok(result) = val.clone().follow_cell_path( + &[PathMember::String { + val: column_name.clone(), + span: *origin_span, + optional: *optional, + }], + insensitive, + ) { + output.push(result); + } else { + return Err(ShellError::CantFindColumn { + col_name: column_name.to_string(), + span: *origin_span, + src_span: val.span(), + }); + } + } else if *optional && matches!(val, Value::Nothing { .. }) { + output.push(Value::nothing(*origin_span)); } else { return Err(ShellError::CantFindColumn { col_name: column_name.to_string(), @@ -1044,36 +1109,25 @@ impl Value { src_span: val.span(), }); } - } else if *optional && matches!(val, Value::Nothing { .. }) { - output.push(Value::nothing(*origin_span)); - } else { - return Err(ShellError::CantFindColumn { - col_name: column_name.to_string(), - span: *origin_span, - src_span: val.span(), - }); } - } - current = Value::List { - vals: output, - span: *span, - }; + current = Value::list(output, span); + } + Value::CustomValue { val, .. } => { + current = val.follow_path_string(column_name.clone(), *origin_span)?; + } + Value::Nothing { .. } if *optional => { + return Ok(Value::nothing(*origin_span)); // short-circuit + } + Value::Error { error, .. } => return Err(*error.to_owned()), + x => { + return Err(ShellError::IncompatiblePathAccess { + type_name: format!("{}", x.get_type()), + span: *origin_span, + }) + } } - Value::CustomValue { val, .. } => { - current = val.follow_path_string(column_name.clone(), *origin_span)?; - } - Value::Nothing { .. } if *optional => { - return Ok(Value::nothing(*origin_span)); // short-circuit - } - Value::Error { error, .. } => return Err(*error.to_owned()), - x => { - return Err(ShellError::IncompatiblePathAccess { - type_name: format!("{}", x.get_type()), - span: *origin_span, - }) - } - }, + } } } // If a single Value::Error was produced by the above (which won't happen if nullify_errors is true), unwrap it now. @@ -1245,6 +1299,8 @@ impl Value { cell_path: &[PathMember], new_val: Value, ) -> Result<(), ShellError> { + let v_span = self.span(); + match cell_path.first() { Some(path_member) => match path_member { PathMember::String { @@ -1254,11 +1310,9 @@ impl Value { } => match self { Value::List { vals, .. } => { for val in vals.iter_mut() { + let v_span = val.span(); match val { - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { let mut found = false; for (col, val) in record.iter_mut() { if col == col_name { @@ -1273,7 +1327,7 @@ impl Value { return Err(ShellError::CantFindColumn { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } } @@ -1288,10 +1342,7 @@ impl Value { } } } - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { let mut found = false; for (col, val) in record.iter_mut() { @@ -1304,7 +1355,7 @@ impl Value { return Err(ShellError::CantFindColumn { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } } @@ -1359,6 +1410,7 @@ impl Value { 0 => Ok(()), 1 => { let path_member = cell_path.first().expect("there is a first"); + let v_span = self.span(); match path_member { PathMember::String { val: col_name, @@ -1367,11 +1419,10 @@ impl Value { } => match self { Value::List { vals, .. } => { for val in vals.iter_mut() { + let v_span = val.span(); + match val { - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { let mut found = false; let mut index = 0; record.cols.retain_mut(|col| { @@ -1388,7 +1439,7 @@ impl Value { return Err(ShellError::CantFindColumn { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } } @@ -1403,10 +1454,7 @@ impl Value { } Ok(()) } - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { let mut found = false; let mut index = 0; record.cols.retain_mut(|col| { @@ -1423,7 +1471,7 @@ impl Value { return Err(ShellError::CantFindColumn { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } Ok(()) @@ -1470,6 +1518,7 @@ impl Value { } _ => { let path_member = cell_path.first().expect("there is a first"); + let v_span = self.span(); match path_member { PathMember::String { val: col_name, @@ -1478,11 +1527,9 @@ impl Value { } => match self { Value::List { vals, .. } => { for val in vals.iter_mut() { + let v_span = val.span(); match val { - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { let mut found = false; for (col, val) in record.iter_mut() { if col == col_name { @@ -1494,7 +1541,7 @@ impl Value { return Err(ShellError::CantFindColumn { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } } @@ -1509,10 +1556,7 @@ impl Value { } Ok(()) } - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { let mut found = false; for (col, val) in record.iter_mut() { @@ -1525,7 +1569,7 @@ impl Value { return Err(ShellError::CantFindColumn { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } Ok(()) @@ -1578,6 +1622,7 @@ impl Value { new_val: Value, head_span: Span, ) -> Result<(), ShellError> { + let v_span = self.span(); match cell_path.first() { Some(path_member) => match path_member { PathMember::String { @@ -1587,18 +1632,16 @@ impl Value { } => match self { Value::List { vals, .. } => { for val in vals.iter_mut() { + let v_span = val.span(); match val { - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { for (col, val) in record.iter_mut() { if col == col_name { if cell_path.len() == 1 { return Err(ShellError::ColumnAlreadyExists { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } else { return val.insert_data_at_cell_path( @@ -1625,17 +1668,14 @@ impl Value { } } } - Value::Record { - val: record, - span: v_span, - } => { + Value::Record { val: record, .. } => { for (col, val) in record.iter_mut() { if col == col_name { if cell_path.len() == 1 { return Err(ShellError::ColumnAlreadyExists { col_name: col_name.to_string(), span: *span, - src_span: *v_span, + src_span: v_span, }); } else { return val.insert_data_at_cell_path( @@ -1649,10 +1689,10 @@ impl Value { record.push(col_name, new_val); } - Value::LazyRecord { val, span } => { + Value::LazyRecord { val, .. } => { // convert to Record first. let mut record = val.collect()?; - record.insert_data_at_cell_path(cell_path, new_val, *span)?; + record.insert_data_at_cell_path(cell_path, new_val, v_span)?; *self = record } other => { @@ -1712,98 +1752,136 @@ impl Value { } pub fn bool(val: bool, span: Span) -> Value { - Value::Bool { val, span } + Value::Bool { + val, + internal_span: span, + } } pub fn int(val: i64, span: Span) -> Value { - Value::Int { val, span } + Value::Int { + val, + internal_span: span, + } } pub fn float(val: f64, span: Span) -> Value { - Value::Float { val, span } + Value::Float { + val, + internal_span: span, + } } pub fn filesize(val: i64, span: Span) -> Value { - Value::Filesize { val, span } + Value::Filesize { + val, + internal_span: span, + } } pub fn duration(val: i64, span: Span) -> Value { - Value::Duration { val, span } + Value::Duration { + val, + internal_span: span, + } } pub fn date(val: DateTime, span: Span) -> Value { - Value::Date { val, span } + Value::Date { + val, + internal_span: span, + } } pub fn range(val: Range, span: Span) -> Value { Value::Range { val: Box::new(val), - span, + internal_span: span, } } pub fn string(val: impl Into, span: Span) -> Value { Value::String { val: val.into(), - span, + internal_span: span, } } pub fn record(val: Record, span: Span) -> Value { - Value::Record { val, span } + Value::Record { + val, + internal_span: span, + } } pub fn list(vals: Vec, span: Span) -> Value { - Value::List { vals, span } + Value::List { + vals, + internal_span: span, + } } pub fn block(val: BlockId, span: Span) -> Value { - Value::Block { val, span } + Value::Block { + val, + internal_span: span, + } } pub fn closure(val: BlockId, captures: HashMap, span: Span) -> Value { Value::Closure { val, captures, - span, + internal_span: span, } } /// Create a new `Nothing` value pub fn nothing(span: Span) -> Value { - Value::Nothing { span } + Value::Nothing { + internal_span: span, + } } pub fn error(error: ShellError, span: Span) -> Value { Value::Error { error: Box::new(error), - span, + internal_span: span, } } pub fn binary(val: impl Into>, span: Span) -> Value { Value::Binary { val: val.into(), - span, + internal_span: span, } } pub fn cell_path(val: CellPath, span: Span) -> Value { - Value::CellPath { val, span } + Value::CellPath { + val, + internal_span: span, + } } pub fn custom_value(val: Box, span: Span) -> Value { - Value::CustomValue { val, span } + Value::CustomValue { + val, + internal_span: span, + } } pub fn lazy_record(val: Box LazyRecord<'a>>, span: Span) -> Value { - Value::LazyRecord { val, span } + Value::LazyRecord { + val, + internal_span: span, + } } pub fn match_pattern(val: MatchPattern, span: Span) -> Value { Value::MatchPattern { val: Box::new(val), - span, + internal_span: span, } } @@ -1919,7 +1997,7 @@ impl Value { impl Default for Value { fn default() -> Self { Value::Nothing { - span: Span::unknown(), + internal_span: Span::unknown(), } } } @@ -2338,30 +2416,27 @@ impl Value { match (self, rhs) { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if let Some(val) = lhs.checked_add(*rhs) { - Ok(Value::Int { val, span }) + Ok(Value::int(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "add operation overflowed".into(), span, help: "Consider using floating point values for increased range by promoting operand with 'into decimal'. Note: float has reduced precision!".into() }) } } - (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: *lhs as f64 + *rhs, - span, - }), - (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Float { - val: *lhs + *rhs as f64, - span, - }), - (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: lhs + rhs, - span, - }), - (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::String { - val: lhs.to_string() + rhs, - span, - }), + (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(*lhs as f64 + *rhs, span)) + } + (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::float(*lhs + *rhs as f64, span)) + } + (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(lhs + rhs, span)) + } + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { + Ok(Value::string(lhs.to_string() + rhs, span)) + } + (Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { if let Some(val) = lhs.checked_add_signed(chrono::Duration::nanoseconds(*rhs)) { - Ok(Value::Date { val, span }) + Ok(Value::date(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "addition operation overflowed".into(), @@ -2372,7 +2447,7 @@ impl Value { } (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { if let Some(val) = lhs.checked_add(*rhs) { - Ok(Value::Duration { val, span }) + Ok(Value::duration(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "add operation overflowed".into(), @@ -2383,7 +2458,7 @@ impl Value { } (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { if let Some(val) = lhs.checked_add(*rhs) { - Ok(Value::Filesize { val, span }) + Ok(Value::filesize(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "add operation overflowed".into(), @@ -2393,8 +2468,8 @@ impl Value { } } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Plus), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(self.span(), Operator::Math(Math::Plus), op, rhs) } _ => Err(ShellError::OperatorMismatch { @@ -2413,26 +2488,25 @@ impl Value { let mut lhs = lhs.clone(); let mut rhs = rhs.clone(); lhs.append(&mut rhs); - Ok(Value::List { vals: lhs, span }) + Ok(Value::list(lhs, span)) } (Value::List { vals: lhs, .. }, val) => { let mut lhs = lhs.clone(); lhs.push(val.clone()); - Ok(Value::List { vals: lhs, span }) + Ok(Value::list(lhs, span)) } (val, Value::List { vals: rhs, .. }) => { let mut rhs = rhs.clone(); rhs.insert(0, val.clone()); - Ok(Value::List { vals: rhs, span }) + Ok(Value::list(rhs, span)) + } + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { + Ok(Value::string(lhs.to_string() + rhs, span)) } - (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::String { - val: lhs.to_string() + rhs, - span, - }), (Value::Binary { val: lhs, .. }, Value::Binary { val: rhs, .. }) => { let mut val = lhs.clone(); val.extend(rhs); - Ok(Value::Binary { val, span }) + Ok(Value::binary(val, span)) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -2448,28 +2522,25 @@ impl Value { match (self, rhs) { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if let Some(val) = lhs.checked_sub(*rhs) { - Ok(Value::Int { val, span }) + Ok(Value::int(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "subtraction operation overflowed".into(), span, help: "Consider using floating point values for increased range by promoting operand with 'into decimal'. Note: float has reduced precision!".into() }) } } - (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: *lhs as f64 - *rhs, - span, - }), - (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Float { - val: *lhs - *rhs as f64, - span, - }), - (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: lhs - rhs, - span, - }), + (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(*lhs as f64 - *rhs, span)) + } + (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::float(*lhs - *rhs as f64, span)) + } + (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(lhs - rhs, span)) + } (Value::Date { val: lhs, .. }, Value::Date { val: rhs, .. }) => { let result = lhs.signed_duration_since(*rhs); if let Some(v) = result.num_nanoseconds() { - Ok(Value::Duration { val: v, span }) + Ok(Value::duration(v, span)) } else { Err(ShellError::OperatorOverflow { msg: "subtraction operation overflowed".into(), @@ -2480,7 +2551,7 @@ impl Value { } (Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { match lhs.checked_sub_signed(chrono::Duration::nanoseconds(*rhs)) { - Some(val) => Ok(Value::Date { val, span }), + Some(val) => Ok(Value::date(val, span)), _ => Err(ShellError::OperatorOverflow { msg: "subtraction operation overflowed".into(), span, @@ -2490,7 +2561,7 @@ impl Value { } (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { if let Some(val) = lhs.checked_sub(*rhs) { - Ok(Value::Duration { val, span }) + Ok(Value::duration(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "subtraction operation overflowed".into(), @@ -2501,7 +2572,7 @@ impl Value { } (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { if let Some(val) = lhs.checked_sub(*rhs) { - Ok(Value::Filesize { val, span }) + Ok(Value::filesize(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "add operation overflowed".into(), @@ -2511,8 +2582,8 @@ impl Value { } } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Minus), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(self.span(), Operator::Math(Math::Minus), op, rhs) } _ => Err(ShellError::OperatorMismatch { @@ -2529,101 +2600,74 @@ impl Value { match (self, rhs) { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if let Some(val) = lhs.checked_mul(*rhs) { - Ok(Value::Int { val, span }) + Ok(Value::int(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "multiply operation overflowed".into(), span, help: "Consider using floating point values for increased range by promoting operand with 'into decimal'. Note: float has reduced precision!".into() }) } } - (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: *lhs as f64 * *rhs, - span, - }), - (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Float { - val: *lhs * *rhs as f64, - span, - }), - (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: lhs * rhs, - span, - }), + (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(*lhs as f64 * *rhs, span)) + } + (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::float(*lhs * *rhs as f64, span)) + } + (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(lhs * rhs, span)) + } (Value::Int { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { - Ok(Value::Filesize { - val: *lhs * *rhs, - span, - }) + Ok(Value::filesize(*lhs * *rhs, span)) } (Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => { - Ok(Value::Filesize { - val: *lhs * *rhs, - span, - }) + Ok(Value::filesize(*lhs * *rhs, span)) } (Value::Float { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { - Ok(Value::Filesize { - val: (*lhs * *rhs as f64) as i64, - span, - }) + Ok(Value::filesize((*lhs * *rhs as f64) as i64, span)) } (Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => { - Ok(Value::Filesize { - val: (*lhs as f64 * *rhs) as i64, - span, - }) + Ok(Value::filesize((*lhs as f64 * *rhs) as i64, span)) } (Value::Int { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { - Ok(Value::Duration { - val: *lhs * *rhs, - span, - }) + Ok(Value::duration(*lhs * *rhs, span)) } (Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => { - Ok(Value::Duration { - val: *lhs * *rhs, - span, - }) + Ok(Value::duration(*lhs * *rhs, span)) } (Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => { - Ok(Value::Duration { - val: (*lhs as f64 * *rhs) as i64, - span, - }) + Ok(Value::duration((*lhs as f64 * *rhs) as i64, span)) } (Value::Float { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { - Ok(Value::Duration { - val: (*lhs * *rhs as f64) as i64, - span, - }) + Ok(Value::duration((*lhs * *rhs as f64) as i64, span)) } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Multiply), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(self.span(), Operator::Math(Math::Multiply), op, rhs) } (Value::Int { val: lhs, .. }, Value::String { val: rhs, .. }) => { let mut res = String::new(); for _ in 0..*lhs { res.push_str(rhs) } - Ok(Value::String { val: res, span }) + Ok(Value::string(res, span)) } (Value::String { val: lhs, .. }, Value::Int { val: rhs, .. }) => { let mut res = String::new(); for _ in 0..*rhs { res.push_str(lhs) } - Ok(Value::String { val: res, span }) + Ok(Value::string(res, span)) } (Value::Int { val: lhs, .. }, Value::List { vals: rhs, .. }) => { let mut res = vec![]; for _ in 0..*lhs { res.append(&mut rhs.clone()) } - Ok(Value::List { vals: res, span }) + Ok(Value::list(res, span)) } (Value::List { vals: lhs, .. }, Value::Int { val: rhs, .. }) => { let mut res = vec![]; for _ in 0..*rhs { res.append(&mut lhs.clone()) } - Ok(Value::List { vals: res, span }) + Ok(Value::list(res, span)) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -2640,15 +2684,9 @@ impl Value { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { if lhs % rhs == 0 { - Ok(Value::Int { - val: lhs / rhs, - span, - }) + Ok(Value::int(lhs / rhs, span)) } else { - Ok(Value::Float { - val: (*lhs as f64) / (*rhs as f64), - span, - }) + Ok(Value::float((*lhs as f64) / (*rhs as f64), span)) } } else { Err(ShellError::DivisionByZero { span: op }) @@ -2656,30 +2694,21 @@ impl Value { } (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Float { - val: *lhs as f64 / *rhs, - span, - }) + Ok(Value::float(*lhs as f64 / *rhs, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Float { - val: *lhs / *rhs as f64, - span, - }) + Ok(Value::float(*lhs / *rhs as f64, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Float { - val: lhs / rhs, - span, - }) + Ok(Value::float(lhs / rhs, span)) } else { Err(ShellError::DivisionByZero { span: op }) } @@ -2687,15 +2716,9 @@ impl Value { (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { if *rhs != 0 { if lhs % rhs == 0 { - Ok(Value::Int { - val: lhs / rhs, - span, - }) + Ok(Value::int(lhs / rhs, span)) } else { - Ok(Value::Float { - val: (*lhs as f64) / (*rhs as f64), - span, - }) + Ok(Value::float((*lhs as f64) / (*rhs as f64), span)) } } else { Err(ShellError::DivisionByZero { span: op }) @@ -2703,20 +2726,17 @@ impl Value { } (Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Filesize { - val: ((*lhs as f64) / (*rhs as f64)) as i64, + Ok(Value::filesize( + ((*lhs as f64) / (*rhs as f64)) as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Filesize { - val: (*lhs as f64 / rhs) as i64, - span, - }) + Ok(Value::filesize((*lhs as f64 / rhs) as i64, span)) } else { Err(ShellError::DivisionByZero { span: op }) } @@ -2724,15 +2744,9 @@ impl Value { (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { if *rhs != 0 { if lhs % rhs == 0 { - Ok(Value::Int { - val: lhs / rhs, - span, - }) + Ok(Value::int(lhs / rhs, span)) } else { - Ok(Value::Float { - val: (*lhs as f64) / (*rhs as f64), - span, - }) + Ok(Value::float((*lhs as f64) / (*rhs as f64), span)) } } else { Err(ShellError::DivisionByZero { span: op }) @@ -2740,26 +2754,23 @@ impl Value { } (Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Duration { - val: ((*lhs as f64) / (*rhs as f64)) as i64, + Ok(Value::duration( + ((*lhs as f64) / (*rhs as f64)) as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Duration { - val: ((*lhs as f64) / rhs) as i64, - span, - }) + Ok(Value::duration(((*lhs as f64) / rhs) as i64, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Divide), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(self.span(), Operator::Math(Math::Divide), op, rhs) } _ => Err(ShellError::OperatorMismatch { @@ -2776,126 +2787,126 @@ impl Value { match (self, rhs) { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Int { - val: (*lhs as f64 / *rhs as f64) + Ok(Value::int( + (*lhs as f64 / *rhs as f64) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Int { - val: (*lhs as f64 / *rhs) + Ok(Value::int( + (*lhs as f64 / *rhs) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Int { - val: (*lhs / *rhs as f64) + Ok(Value::int( + (*lhs / *rhs as f64) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Int { - val: (lhs / rhs) + Ok(Value::int( + (lhs / rhs) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Filesize { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Int { - val: (*lhs as f64 / *rhs as f64) + Ok(Value::int( + (*lhs as f64 / *rhs as f64) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Filesize { - val: ((*lhs as f64) / (*rhs as f64)) + Ok(Value::filesize( + ((*lhs as f64) / (*rhs as f64)) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Filesize { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Filesize { - val: (*lhs as f64 / *rhs) + Ok(Value::filesize( + (*lhs as f64 / *rhs) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Int { - val: (*lhs as f64 / *rhs as f64) + Ok(Value::int( + (*lhs as f64 / *rhs as f64) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Duration { - val: (*lhs as f64 / *rhs as f64) + Ok(Value::duration( + (*lhs as f64 / *rhs as f64) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Duration { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Duration { - val: (*lhs as f64 / *rhs) + Ok(Value::duration( + (*lhs as f64 / *rhs) .clamp(std::i64::MIN as f64, std::i64::MAX as f64) .floor() as i64, span, - }) + )) } else { Err(ShellError::DivisionByZero { span: op }) } } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Divide), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(self.span(), Operator::Math(Math::Divide), op, rhs) } _ => Err(ShellError::OperatorMismatch { @@ -2909,8 +2920,13 @@ impl Value { } pub fn lt(&self, op: Span, rhs: &Value, span: Span) -> Result { - if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) { - return lhs.operation(*span, Operator::Comparison(Comparison::LessThan), op, rhs); + if let (Value::CustomValue { val: lhs, .. }, rhs) = (self, rhs) { + return lhs.operation( + self.span(), + Operator::Comparison(Comparison::LessThan), + op, + rhs, + ); } if matches!(self, Value::Nothing { .. }) || matches!(rhs, Value::Nothing { .. }) { @@ -2931,10 +2947,7 @@ impl Value { } if let Some(ordering) = self.partial_cmp(rhs) { - Ok(Value::Bool { - val: matches!(ordering, Ordering::Less), - span, - }) + Ok(Value::bool(matches!(ordering, Ordering::Less), span)) } else { Err(ShellError::OperatorMismatch { op_span: op, @@ -2947,9 +2960,9 @@ impl Value { } pub fn lte(&self, op: Span, rhs: &Value, span: Span) -> Result { - if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) { + if let (Value::CustomValue { val: lhs, .. }, rhs) = (self, rhs) { return lhs.operation( - *span, + self.span(), Operator::Comparison(Comparison::LessThanOrEqual), op, rhs, @@ -2974,10 +2987,7 @@ impl Value { } self.partial_cmp(rhs) - .map(|ordering| Value::Bool { - val: matches!(ordering, Ordering::Less | Ordering::Equal), - span, - }) + .map(|ordering| Value::bool(matches!(ordering, Ordering::Less | Ordering::Equal), span)) .ok_or(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type().to_string(), @@ -2988,9 +2998,9 @@ impl Value { } pub fn gt(&self, op: Span, rhs: &Value, span: Span) -> Result { - if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) { + if let (Value::CustomValue { val: lhs, .. }, rhs) = (self, rhs) { return lhs.operation( - *span, + self.span(), Operator::Comparison(Comparison::GreaterThan), op, rhs, @@ -3015,10 +3025,7 @@ impl Value { } self.partial_cmp(rhs) - .map(|ordering| Value::Bool { - val: matches!(ordering, Ordering::Greater), - span, - }) + .map(|ordering| Value::bool(matches!(ordering, Ordering::Greater), span)) .ok_or(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type().to_string(), @@ -3029,9 +3036,9 @@ impl Value { } pub fn gte(&self, op: Span, rhs: &Value, span: Span) -> Result { - if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) { + if let (Value::CustomValue { val: lhs, .. }, rhs) = (self, rhs) { return lhs.operation( - *span, + self.span(), Operator::Comparison(Comparison::GreaterThanOrEqual), op, rhs, @@ -3056,10 +3063,10 @@ impl Value { } match self.partial_cmp(rhs) { - Some(ordering) => Ok(Value::Bool { - val: matches!(ordering, Ordering::Greater | Ordering::Equal), + Some(ordering) => Ok(Value::bool( + matches!(ordering, Ordering::Greater | Ordering::Equal), span, - }), + )), None => Err(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type().to_string(), @@ -3071,19 +3078,21 @@ impl Value { } pub fn eq(&self, op: Span, rhs: &Value, span: Span) -> Result { - if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) { - return lhs.operation(*span, Operator::Comparison(Comparison::Equal), op, rhs); + if let (Value::CustomValue { val: lhs, .. }, rhs) = (self, rhs) { + return lhs.operation( + self.span(), + Operator::Comparison(Comparison::Equal), + op, + rhs, + ); } if let Some(ordering) = self.partial_cmp(rhs) { - Ok(Value::Bool { - val: matches!(ordering, Ordering::Equal), - span, - }) + Ok(Value::bool(matches!(ordering, Ordering::Equal), span)) } else { match (self, rhs) { (Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => { - Ok(Value::Bool { val: false, span }) + Ok(Value::bool(false, span)) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3097,19 +3106,21 @@ impl Value { } pub fn ne(&self, op: Span, rhs: &Value, span: Span) -> Result { - if let (Value::CustomValue { val: lhs, span }, rhs) = (self, rhs) { - return lhs.operation(*span, Operator::Comparison(Comparison::NotEqual), op, rhs); + if let (Value::CustomValue { val: lhs, .. }, rhs) = (self, rhs) { + return lhs.operation( + self.span(), + Operator::Comparison(Comparison::NotEqual), + op, + rhs, + ); } if let Some(ordering) = self.partial_cmp(rhs) { - Ok(Value::Bool { - val: !matches!(ordering, Ordering::Equal), - span, - }) + Ok(Value::bool(!matches!(ordering, Ordering::Equal), span)) } else { match (self, rhs) { (Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => { - Ok(Value::Bool { val: true, span }) + Ok(Value::bool(true, span)) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3124,22 +3135,14 @@ impl Value { pub fn r#in(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool { - val: rhs.contains(lhs), - span, - }), - (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::Bool { - val: rhs.contains(lhs), - span, - }), - (lhs, Value::List { vals: rhs, .. }) => Ok(Value::Bool { - val: rhs.contains(lhs), - span, - }), - (Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => Ok(Value::Bool { - val: rhs.cols.contains(lhs), - span, - }), + (lhs, Value::Range { val: rhs, .. }) => Ok(Value::bool(rhs.contains(lhs), span)), + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { + Ok(Value::bool(rhs.contains(lhs), span)) + } + (lhs, Value::List { vals: rhs, .. }) => Ok(Value::bool(rhs.contains(lhs), span)), + (Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => { + Ok(Value::bool(rhs.cols.contains(lhs), span)) + } (Value::String { .. } | Value::Int { .. }, Value::CellPath { val: rhs, .. }) => { let val = rhs.members.iter().any(|member| match (self, member) { (Value::Int { val: lhs, .. }, PathMember::Int { val: rhs, .. }) => { @@ -3155,19 +3158,18 @@ impl Value { ), }); - Ok(Value::Bool { val, span }) + Ok(Value::bool(val, span)) } (Value::CellPath { val: lhs, .. }, Value::CellPath { val: rhs, .. }) => { - Ok(Value::Bool { - val: rhs - .members + Ok(Value::bool( + rhs.members .windows(lhs.members.len()) .any(|member_window| member_window == rhs.members), span, - }) + )) } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Comparison(Comparison::In), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(self.span(), Operator::Comparison(Comparison::In), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3181,22 +3183,14 @@ impl Value { pub fn not_in(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (lhs, Value::Range { val: rhs, .. }) => Ok(Value::Bool { - val: !rhs.contains(lhs), - span, - }), - (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::Bool { - val: !rhs.contains(lhs), - span, - }), - (lhs, Value::List { vals: rhs, .. }) => Ok(Value::Bool { - val: !rhs.contains(lhs), - span, - }), - (Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => Ok(Value::Bool { - val: !rhs.cols.contains(lhs), - span, - }), + (lhs, Value::Range { val: rhs, .. }) => Ok(Value::bool(!rhs.contains(lhs), span)), + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { + Ok(Value::bool(!rhs.contains(lhs), span)) + } + (lhs, Value::List { vals: rhs, .. }) => Ok(Value::bool(!rhs.contains(lhs), span)), + (Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => { + Ok(Value::bool(!rhs.cols.contains(lhs), span)) + } (Value::String { .. } | Value::Int { .. }, Value::CellPath { val: rhs, .. }) => { let val = rhs.members.iter().any(|member| match (self, member) { (Value::Int { val: lhs, .. }, PathMember::Int { val: rhs, .. }) => { @@ -3212,20 +3206,22 @@ impl Value { ), }); - Ok(Value::Bool { val, span }) + Ok(Value::bool(val, span)) } (Value::CellPath { val: lhs, .. }, Value::CellPath { val: rhs, .. }) => { - Ok(Value::Bool { - val: rhs - .members + Ok(Value::bool( + rhs.members .windows(lhs.members.len()) .all(|member_window| member_window != rhs.members), span, - }) - } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Comparison(Comparison::NotIn), op, rhs) + )) } + (Value::CustomValue { val: lhs, .. }, rhs) => lhs.operation( + self.span(), + Operator::Comparison(Comparison::NotIn), + op, + rhs, + ), _ => Err(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type().to_string(), @@ -3244,14 +3240,9 @@ impl Value { invert: bool, span: Span, ) -> Result { + let rhs_span = rhs.span(); match (self, rhs) { - ( - Value::String { val: lhs, .. }, - Value::String { - val: rhs, - span: rhs_span, - }, - ) => { + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { let is_match = match engine_state.regex_cache.try_lock() { Ok(mut cache) => { if let Some(regex) = cache.get(rhs) { @@ -3262,7 +3253,7 @@ impl Value { format!("{e}"), "value originated from here".into(), span, - *rhs_span, + rhs_span, ) })?; let ret = regex.is_match(lhs); @@ -3276,24 +3267,24 @@ impl Value { format!("{e}"), "value originated from here".into(), span, - *rhs_span, + rhs_span, ) })?; regex.is_match(lhs) } }; - Ok(Value::Bool { - val: if invert { + Ok(Value::bool( + if invert { !is_match.unwrap_or(false) } else { is_match.unwrap_or(true) }, span, - }) + )) } - (Value::CustomValue { val: lhs, span }, rhs) => lhs.operation( - *span, + (Value::CustomValue { val: lhs, .. }, rhs) => lhs.operation( + span, if invert { Operator::Comparison(Comparison::NotRegexMatch) } else { @@ -3314,13 +3305,15 @@ impl Value { pub fn starts_with(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::Bool { - val: lhs.starts_with(rhs), - span, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Comparison(Comparison::StartsWith), op, rhs) + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { + Ok(Value::bool(lhs.starts_with(rhs), span)) } + (Value::CustomValue { val: lhs, .. }, rhs) => lhs.operation( + self.span(), + Operator::Comparison(Comparison::StartsWith), + op, + rhs, + ), _ => Err(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type().to_string(), @@ -3333,13 +3326,15 @@ impl Value { pub fn ends_with(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => Ok(Value::Bool { - val: lhs.ends_with(rhs), - span, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Comparison(Comparison::EndsWith), op, rhs) + (Value::String { val: lhs, .. }, Value::String { val: rhs, .. }) => { + Ok(Value::bool(lhs.ends_with(rhs), span)) } + (Value::CustomValue { val: lhs, .. }, rhs) => lhs.operation( + self.span(), + Operator::Comparison(Comparison::EndsWith), + op, + rhs, + ), _ => Err(ShellError::OperatorMismatch { op_span: op, lhs_ty: self.get_type().to_string(), @@ -3352,12 +3347,11 @@ impl Value { pub fn bit_shl(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int { - span, - val: *lhs << rhs, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Bits(Bits::ShiftLeft), op, rhs) + (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::int(*lhs << rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Bits(Bits::ShiftLeft), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3371,12 +3365,11 @@ impl Value { pub fn bit_shr(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int { - span, - val: *lhs >> rhs, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Bits(Bits::ShiftRight), op, rhs) + (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::int(*lhs >> rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Bits(Bits::ShiftRight), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3390,12 +3383,11 @@ impl Value { pub fn bit_or(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int { - span, - val: *lhs | rhs, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Bits(Bits::BitOr), op, rhs) + (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::int(*lhs | rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Bits(Bits::BitOr), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3409,12 +3401,11 @@ impl Value { pub fn bit_xor(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int { - span, - val: *lhs ^ rhs, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Bits(Bits::BitXor), op, rhs) + (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::int(*lhs ^ rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Bits(Bits::BitXor), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3428,12 +3419,11 @@ impl Value { pub fn bit_and(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Int { - span, - val: *lhs & rhs, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Bits(Bits::BitAnd), op, rhs) + (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::int(*lhs & rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Bits(Bits::BitAnd), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3449,46 +3439,34 @@ impl Value { match (self, rhs) { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Int { - val: lhs % rhs, - span, - }) + Ok(Value::int(lhs % rhs, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Float { - val: *lhs as f64 % *rhs, - span, - }) + Ok(Value::float(*lhs as f64 % *rhs, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if *rhs != 0 { - Ok(Value::Float { - val: *lhs % *rhs as f64, - span, - }) + Ok(Value::float(*lhs % *rhs as f64, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { if *rhs != 0.0 { - Ok(Value::Float { - val: lhs % rhs, - span, - }) + Ok(Value::float(lhs % rhs, span)) } else { Err(ShellError::DivisionByZero { span: op }) } } - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Modulo), op, rhs) + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Math(Math::Modulo), op, rhs) } _ => Err(ShellError::OperatorMismatch { @@ -3503,12 +3481,11 @@ impl Value { pub fn and(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => Ok(Value::Bool { - val: *lhs && *rhs, - span, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Boolean(Boolean::And), op, rhs) + (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => { + Ok(Value::bool(*lhs && *rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Boolean(Boolean::And), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3522,12 +3499,11 @@ impl Value { pub fn or(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => Ok(Value::Bool { - val: *lhs || *rhs, - span, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Boolean(Boolean::Or), op, rhs) + (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => { + Ok(Value::bool(*lhs || *rhs, span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Boolean(Boolean::Or), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3541,12 +3517,11 @@ impl Value { pub fn xor(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => Ok(Value::Bool { - val: (*lhs && !*rhs) || (!*lhs && *rhs), - span, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Boolean(Boolean::Xor), op, rhs) + (Value::Bool { val: lhs, .. }, Value::Bool { val: rhs, .. }) => { + Ok(Value::bool((*lhs && !*rhs) || (!*lhs && *rhs), span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Boolean(Boolean::Xor), op, rhs) } _ => Err(ShellError::OperatorMismatch { op_span: op, @@ -3562,25 +3537,22 @@ impl Value { match (self, rhs) { (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { if let Some(val) = lhs.checked_pow(*rhs as u32) { - Ok(Value::Int { val, span }) + Ok(Value::int(val, span)) } else { Err(ShellError::OperatorOverflow { msg: "pow operation overflowed".into(), span, help: "Consider using floating point values for increased range by promoting operand with 'into decimal'. Note: float has reduced precision!".into() }) } } - (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: (*lhs as f64).powf(*rhs), - span, - }), - (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => Ok(Value::Float { - val: lhs.powf(*rhs as f64), - span, - }), - (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => Ok(Value::Float { - val: lhs.powf(*rhs), - span, - }), - (Value::CustomValue { val: lhs, span }, rhs) => { - lhs.operation(*span, Operator::Math(Math::Pow), op, rhs) + (Value::Int { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float((*lhs as f64).powf(*rhs), span)) + } + (Value::Float { val: lhs, .. }, Value::Int { val: rhs, .. }) => { + Ok(Value::float(lhs.powf(*rhs as f64), span)) + } + (Value::Float { val: lhs, .. }, Value::Float { val: rhs, .. }) => { + Ok(Value::float(lhs.powf(*rhs), span)) + } + (Value::CustomValue { val: lhs, .. }, rhs) => { + lhs.operation(span, Operator::Math(Math::Pow), op, rhs) } _ => Err(ShellError::OperatorMismatch { @@ -3901,14 +3873,9 @@ mod tests { #[test] fn test_list() { - let list_with_no_values = Value::List { - vals: vec![], - span: Span::unknown(), - }; - let list_with_one_empty_string = Value::List { - vals: vec![Value::string("", Span::unknown())], - span: Span::unknown(), - }; + let list_with_no_values = Value::list(vec![], Span::unknown()); + let list_with_one_empty_string = + Value::list(vec![Value::string("", Span::unknown())], Span::unknown()); assert!(list_with_no_values.is_empty()); assert!(!list_with_one_empty_string.is_empty()); @@ -3949,29 +3916,24 @@ mod tests { #[test] fn test_list() { - let list_of_ints = Value::List { - vals: vec![Value::int(0, Span::unknown())], - span: Span::unknown(), - }; - let list_of_floats = Value::List { - vals: vec![Value::float(0.0, Span::unknown())], - span: Span::unknown(), - }; - let list_of_ints_and_floats = Value::List { - vals: vec![ + let list_of_ints = Value::list(vec![Value::int(0, Span::unknown())], Span::unknown()); + let list_of_floats = + Value::list(vec![Value::float(0.0, Span::unknown())], Span::unknown()); + let list_of_ints_and_floats = Value::list( + vec![ Value::int(0, Span::unknown()), Value::float(0.0, Span::unknown()), ], - span: Span::unknown(), - }; - let list_of_ints_and_floats_and_bools = Value::List { - vals: vec![ + Span::unknown(), + ); + let list_of_ints_and_floats_and_bools = Value::list( + vec![ Value::int(0, Span::unknown()), Value::float(0.0, Span::unknown()), Value::bool(false, Span::unknown()), ], - span: Span::unknown(), - }; + Span::unknown(), + ); assert_eq!(list_of_ints.get_type(), Type::List(Box::new(Type::Int))); assert_eq!(list_of_floats.get_type(), Type::List(Box::new(Type::Float))); assert_eq!( @@ -3992,13 +3954,13 @@ mod tests { #[test] fn test_datetime() { - let string = Value::Date { - val: DateTime::from_naive_utc_and_offset( + let string = Value::date( + DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_millis(-123456789).unwrap(), FixedOffset::east_opt(0).unwrap(), ), - span: Span::unknown(), - } + Span::unknown(), + ) .into_string("", &Default::default()); // We need to cut the humanized part off for tests to work, because @@ -4009,13 +3971,13 @@ mod tests { #[test] fn test_negative_year_datetime() { - let string = Value::Date { - val: DateTime::from_naive_utc_and_offset( + let string = Value::date( + DateTime::from_naive_utc_and_offset( NaiveDateTime::from_timestamp_millis(-72135596800000).unwrap(), FixedOffset::east_opt(0).unwrap(), ), - span: Span::unknown(), - } + Span::unknown(), + ) .into_string("", &Default::default()); // We need to cut the humanized part off for tests to work, because diff --git a/crates/nu-protocol/src/value/range.rs b/crates/nu-protocol/src/value/range.rs index e09f4f1b0..d7e957277 100644 --- a/crates/nu-protocol/src/value/range.rs +++ b/crates/nu-protocol/src/value/range.rs @@ -171,15 +171,12 @@ impl RangeIterator { let is_end_inclusive = range.is_end_inclusive(); let start = match range.from { - Value::Nothing { .. } => Value::Int { val: 0, span }, + Value::Nothing { .. } => Value::int(0, span), x => x, }; let end = match range.to { - Value::Nothing { .. } => Value::Int { - val: i64::MAX, - span, - }, + Value::Nothing { .. } => Value::int(i64::MAX, span), x => x, }; @@ -215,10 +212,9 @@ impl Iterator for RangeIterator { let Some(ordering) = ordering else { self.done = true; - return Some(Value::Error { - error: Box::new(ShellError::CannotCreateRange { span: self.span }), - span: self.span, - }); + return Some(Value::error(ShellError::CannotCreateRange { span: self.span }, + self.span, + )); }; let desired_ordering = if self.moves_up { @@ -236,10 +232,7 @@ impl Iterator for RangeIterator { Err(error) => { self.done = true; - return Some(Value::Error { - error: Box::new(error), - span: self.span, - }); + return Some(Value::error(error, self.span)); } }; std::mem::swap(&mut self.curr, &mut next); diff --git a/crates/nu-protocol/src/value/stream.rs b/crates/nu-protocol/src/value/stream.rs index b812ef908..13bc37944 100644 --- a/crates/nu-protocol/src/value/stream.rs +++ b/crates/nu-protocol/src/value/stream.rs @@ -108,10 +108,7 @@ impl Iterator for RawStream { v.insert(0, b); } } - Value::Binary { - val: v, - span: self.span, - } + Value::binary(v, self.span) }) }) } else { @@ -129,10 +126,7 @@ impl Iterator for RawStream { match String::from_utf8(v.clone()) { Ok(s) => { // Great, we have a complete string, let's output it - Some(Ok(Value::String { - val: s, - span: self.span, - })) + Some(Ok(Value::string(s, self.span))) } Err(err) => { // Okay, we *might* have a string but we've also got some errors @@ -146,10 +140,7 @@ impl Iterator for RawStream { // that it's not just a character spanning two frames. // We now know we are definitely binary, so switch to binary and stay there. self.is_binary = true; - Some(Ok(Value::Binary { - val: v, - span: self.span, - })) + Some(Ok(Value::binary(v, self.span))) } else { // Okay, we have a tiny bit of error at the end of the buffer. This could very well be // a character that spans two frames. Since this is the case, remove the error from @@ -159,17 +150,11 @@ impl Iterator for RawStream { let buf = v[0..err.utf8_error().valid_up_to()].to_vec(); match String::from_utf8(buf) { - Ok(s) => Some(Ok(Value::String { - val: s, - span: self.span, - })), + Ok(s) => Some(Ok(Value::string(s, self.span))), Err(_) => { // Something is definitely wrong. Switch to binary, and stay there self.is_binary = true; - Some(Ok(Value::Binary { - val: v, - span: self.span, - })) + Some(Ok(Value::binary(v, self.span))) } } } @@ -179,10 +164,7 @@ impl Iterator for RawStream { Err(e) => Some(Err(e)), } } else if !self.leftover.is_empty() { - let output = Ok(Value::Binary { - val: self.leftover.clone(), - span: self.span, - }); + let output = Ok(Value::binary(self.leftover.clone(), self.span)); self.leftover.clear(); Some(output) diff --git a/crates/nu-protocol/src/value/unit.rs b/crates/nu-protocol/src/value/unit.rs index 6587d9b8e..46ddf81a9 100644 --- a/crates/nu-protocol/src/value/unit.rs +++ b/crates/nu-protocol/src/value/unit.rs @@ -34,72 +34,39 @@ pub enum Unit { impl Unit { pub fn to_value(&self, size: i64, span: Span) -> Result { match self { - Unit::Byte => Ok(Value::Filesize { val: size, span }), - Unit::Kilobyte => Ok(Value::Filesize { - val: size * 1000, + Unit::Byte => Ok(Value::filesize(size, span)), + Unit::Kilobyte => Ok(Value::filesize(size * 1000, span)), + Unit::Megabyte => Ok(Value::filesize(size * 1000 * 1000, span)), + Unit::Gigabyte => Ok(Value::filesize(size * 1000 * 1000 * 1000, span)), + Unit::Terabyte => Ok(Value::filesize(size * 1000 * 1000 * 1000 * 1000, span)), + Unit::Petabyte => Ok(Value::filesize( + size * 1000 * 1000 * 1000 * 1000 * 1000, span, - }), - Unit::Megabyte => Ok(Value::Filesize { - val: size * 1000 * 1000, + )), + Unit::Exabyte => Ok(Value::filesize( + size * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, span, - }), - Unit::Gigabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000, - span, - }), - Unit::Terabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000 * 1000, - span, - }), - Unit::Petabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000 * 1000 * 1000, - span, - }), - Unit::Exabyte => Ok(Value::Filesize { - val: size * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, - span, - }), + )), - Unit::Kibibyte => Ok(Value::Filesize { - val: size * 1024, + Unit::Kibibyte => Ok(Value::filesize(size * 1024, span)), + Unit::Mebibyte => Ok(Value::filesize(size * 1024 * 1024, span)), + Unit::Gibibyte => Ok(Value::filesize(size * 1024 * 1024 * 1024, span)), + Unit::Tebibyte => Ok(Value::filesize(size * 1024 * 1024 * 1024 * 1024, span)), + Unit::Pebibyte => Ok(Value::filesize( + size * 1024 * 1024 * 1024 * 1024 * 1024, span, - }), - Unit::Mebibyte => Ok(Value::Filesize { - val: size * 1024 * 1024, + )), + Unit::Exbibyte => Ok(Value::filesize( + size * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, span, - }), - Unit::Gibibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024, - span, - }), - Unit::Tebibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024 * 1024, - span, - }), - Unit::Pebibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024 * 1024 * 1024, - span, - }), - Unit::Exbibyte => Ok(Value::Filesize { - val: size * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, - span, - }), + )), - Unit::Nanosecond => Ok(Value::Duration { val: size, span }), - Unit::Microsecond => Ok(Value::Duration { - val: size * 1000, - span, - }), - Unit::Millisecond => Ok(Value::Duration { - val: size * 1000 * 1000, - span, - }), - Unit::Second => Ok(Value::Duration { - val: size * 1000 * 1000 * 1000, - span, - }), + Unit::Nanosecond => Ok(Value::duration(size, span)), + Unit::Microsecond => Ok(Value::duration(size * 1000, span)), + Unit::Millisecond => Ok(Value::duration(size * 1000 * 1000, span)), + Unit::Second => Ok(Value::duration(size * 1000 * 1000 * 1000, span)), Unit::Minute => match size.checked_mul(1000 * 1000 * 1000 * 60) { - Some(val) => Ok(Value::Duration { val, span }), + Some(val) => Ok(Value::duration(val, span)), None => Err(ShellError::GenericError( "duration too large".into(), "duration too large".into(), @@ -109,7 +76,7 @@ impl Unit { )), }, Unit::Hour => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60) { - Some(val) => Ok(Value::Duration { val, span }), + Some(val) => Ok(Value::duration(val, span)), None => Err(ShellError::GenericError( "duration too large".into(), "duration too large".into(), @@ -119,7 +86,7 @@ impl Unit { )), }, Unit::Day => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24) { - Some(val) => Ok(Value::Duration { val, span }), + Some(val) => Ok(Value::duration(val, span)), None => Err(ShellError::GenericError( "duration too large".into(), "duration too large".into(), @@ -129,7 +96,7 @@ impl Unit { )), }, Unit::Week => match size.checked_mul(1000 * 1000 * 1000 * 60 * 60 * 24 * 7) { - Some(val) => Ok(Value::Duration { val, span }), + Some(val) => Ok(Value::duration(val, span)), None => Err(ShellError::GenericError( "duration too large".into(), "duration too large".into(), diff --git a/crates/nu-protocol/tests/test_pipeline_data.rs b/crates/nu-protocol/tests/test_pipeline_data.rs index b529c35f0..6675f6a04 100644 --- a/crates/nu-protocol/tests/test_pipeline_data.rs +++ b/crates/nu-protocol/tests/test_pipeline_data.rs @@ -4,21 +4,12 @@ use nu_protocol::{IntoPipelineData, Span, Value}; fn test_convert_pipeline_data_to_value() { // Setup PipelineData let value_val = 10; - let value = Value::Int { - val: value_val, - span: Span::new(1, 3), - }; + let value = Value::int(value_val, Span::new(1, 3)); let pipeline_data = value.into_pipeline_data(); // Test that conversion into Value is correct let new_span = Span::new(5, 6); let converted_value = pipeline_data.into_value(new_span); - assert_eq!( - converted_value, - Value::Int { - val: value_val, - span: new_span - } - ); + assert_eq!(converted_value, Value::int(value_val, new_span)); } diff --git a/crates/nu-protocol/tests/test_value.rs b/crates/nu-protocol/tests/test_value.rs index 91a72b05e..0766657ba 100644 --- a/crates/nu-protocol/tests/test_value.rs +++ b/crates/nu-protocol/tests/test_value.rs @@ -9,9 +9,7 @@ fn test_comparison_nothing() { Value::test_float(1.0), ]; - let nothing = Value::Nothing { - span: Span::test_data(), - }; + let nothing = Value::nothing(Span::test_data()); for value in values { assert!(matches!( diff --git a/crates/nu-table/src/types/expanded.rs b/crates/nu-table/src/types/expanded.rs index 5916ef1b3..3b2ad16b8 100644 --- a/crates/nu-table/src/types/expanded.rs +++ b/crates/nu-table/src/types/expanded.rs @@ -403,9 +403,10 @@ fn expand_table_value( return Ok(Some((value_to_string_clean(value, cfg), false))); } + let span = value.span(); match value { - Value::List { vals, span } => { - let mut inner_cfg = dive_options(cfg, *span); + Value::List { vals, .. } => { + let mut inner_cfg = dive_options(cfg, span); inner_cfg.opts.width = value_width; let table = expanded_table_list(vals, inner_cfg)?; @@ -427,7 +428,7 @@ fn expand_table_value( } } } - Value::Record { val: record, span } => { + Value::Record { val: record, .. } => { if record.is_empty() { // Like list case return styled string instead of empty value return Ok(Some(( @@ -436,7 +437,7 @@ fn expand_table_value( ))); } - let mut inner_cfg = dive_options(cfg, *span); + let mut inner_cfg = dive_options(cfg, span); inner_cfg.opts.width = value_width; let result = expanded_table_kv(record, inner_cfg)?; match result { @@ -484,14 +485,15 @@ fn expanded_table_entry2(item: &Value, cfg: Cfg<'_>) -> NuText { return nu_value_to_string_clean(item, cfg.opts.config, cfg.opts.style_computer); } + let span = item.span(); match &item { - Value::Record { val: record, span } => { + Value::Record { val: record, .. } => { if record.is_empty() { return nu_value_to_string(item, cfg.opts.config, cfg.opts.style_computer); } // we verify what is the structure of a Record cause it might represent - let inner_cfg = dive_options(&cfg, *span); + let inner_cfg = dive_options(&cfg, span); let table = expanded_table_kv(record, inner_cfg); match table { @@ -499,7 +501,7 @@ fn expanded_table_entry2(item: &Value, cfg: Cfg<'_>) -> NuText { _ => nu_value_to_string(item, cfg.opts.config, cfg.opts.style_computer), } } - Value::List { vals, span } => { + Value::List { vals, .. } => { if cfg.format.flatten && is_simple_list(vals) { return value_list_to_string( vals, @@ -509,7 +511,7 @@ fn expanded_table_entry2(item: &Value, cfg: Cfg<'_>) -> NuText { ); } - let inner_cfg = dive_options(&cfg, *span); + let inner_cfg = dive_options(&cfg, span); let table = expanded_table_list(vals, inner_cfg); let out = match table { diff --git a/crates/nu_plugin_custom_values/src/cool_custom_value.rs b/crates/nu_plugin_custom_values/src/cool_custom_value.rs index 757e6c0b8..76150876d 100644 --- a/crates/nu_plugin_custom_values/src/cool_custom_value.rs +++ b/crates/nu_plugin_custom_values/src/cool_custom_value.rs @@ -14,22 +14,20 @@ impl CoolCustomValue { } pub fn into_value(self, span: Span) -> Value { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } pub fn try_from_value(value: &Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => { + Value::CustomValue { val, .. } => { if let Some(cool) = val.as_any().downcast_ref::() { Ok(cool.clone()) } else { Err(ShellError::CantConvert { to_type: "cool".into(), from_type: "non-cool".into(), - span: *span, + span, help: None, }) } @@ -37,7 +35,7 @@ impl CoolCustomValue { x => Err(ShellError::CantConvert { to_type: "cool".into(), from_type: x.get_type().to_string(), - span: x.span(), + span, help: None, }), } @@ -47,10 +45,7 @@ impl CoolCustomValue { #[typetag::serde] impl CustomValue for CoolCustomValue { fn clone_value(&self, span: nu_protocol::Span) -> Value { - Value::CustomValue { - val: Box::new(self.clone()), - span, - } + Value::custom_value(Box::new(self.clone()), span) } fn value_string(&self) -> String { @@ -58,10 +53,10 @@ impl CustomValue for CoolCustomValue { } fn to_base_value(&self, span: nu_protocol::Span) -> Result { - Ok(Value::String { - val: format!("I used to be a custom value! My data was ({})", self.cool), + Ok(Value::string( + format!("I used to be a custom value! My data was ({})", self.cool), span, - }) + )) } fn as_any(&self) -> &dyn std::any::Any { diff --git a/crates/nu_plugin_custom_values/src/second_custom_value.rs b/crates/nu_plugin_custom_values/src/second_custom_value.rs index 48eff6d0e..805cacee4 100644 --- a/crates/nu_plugin_custom_values/src/second_custom_value.rs +++ b/crates/nu_plugin_custom_values/src/second_custom_value.rs @@ -14,27 +14,25 @@ impl SecondCustomValue { } pub fn into_value(self, span: Span) -> Value { - Value::CustomValue { - val: Box::new(self), - span, - } + Value::custom_value(Box::new(self), span) } pub fn try_from_value(value: &Value) -> Result { + let span = value.span(); match value { - Value::CustomValue { val, span } => match val.as_any().downcast_ref::() { + Value::CustomValue { val, .. } => match val.as_any().downcast_ref::() { Some(value) => Ok(value.clone()), None => Err(ShellError::CantConvert { to_type: "cool".into(), from_type: "non-cool".into(), - span: *span, + span, help: None, }), }, x => Err(ShellError::CantConvert { to_type: "cool".into(), from_type: x.get_type().to_string(), - span: x.span(), + span, help: None, }), } @@ -44,10 +42,7 @@ impl SecondCustomValue { #[typetag::serde] impl CustomValue for SecondCustomValue { fn clone_value(&self, span: nu_protocol::Span) -> Value { - Value::CustomValue { - val: Box::new(self.clone()), - span, - } + Value::custom_value(Box::new(self.clone()), span) } fn value_string(&self) -> String { @@ -55,13 +50,13 @@ impl CustomValue for SecondCustomValue { } fn to_base_value(&self, span: nu_protocol::Span) -> Result { - Ok(Value::String { - val: format!( + Ok(Value::string( + format!( "I used to be a DIFFERENT custom value! ({})", self.something ), span, - }) + )) } fn as_any(&self) -> &dyn std::any::Any { diff --git a/crates/nu_plugin_example/src/example.rs b/crates/nu_plugin_example/src/example.rs index 7245c5508..643fcb0c1 100644 --- a/crates/nu_plugin_example/src/example.rs +++ b/crates/nu_plugin_example/src/example.rs @@ -53,7 +53,7 @@ impl Example { pub fn test1(&self, call: &EvaluatedCall, input: &Value) -> Result { self.print_values(1, call, input)?; - Ok(Value::Nothing { span: call.head }) + Ok(Value::nothing(call.head)) } pub fn test2(&self, call: &EvaluatedCall, input: &Value) -> Result { @@ -77,10 +77,7 @@ impl Example { }) .collect::>(); - Ok(Value::List { - vals, - span: call.head, - }) + Ok(Value::list(vals, call.head)) } pub fn test3(&self, call: &EvaluatedCall, input: &Value) -> Result { diff --git a/crates/nu_plugin_formats/src/from/eml.rs b/crates/nu_plugin_formats/src/from/eml.rs index fc792f341..50d62f781 100644 --- a/crates/nu_plugin_formats/src/from/eml.rs +++ b/crates/nu_plugin_formats/src/from/eml.rs @@ -90,23 +90,12 @@ Test' | from eml -b 1" fn emailaddress_to_value(span: Span, email_address: &EmailAddress) -> Value { let (n, a) = match email_address { - EmailAddress::AddressOnly { address } => ( - Value::nothing(span), - Value::String { - val: address.to_string(), - span, - }, - ), - EmailAddress::NameAndEmailAddress { name, address } => ( - Value::String { - val: name.to_string(), - span, - }, - Value::String { - val: address.to_string(), - span, - }, - ), + EmailAddress::AddressOnly { address } => { + (Value::nothing(span), Value::string(address, span)) + } + EmailAddress::NameAndEmailAddress { name, address } => { + (Value::string(name, span), Value::string(address, span)) + } }; Value::record( @@ -123,13 +112,13 @@ fn headerfieldvalue_to_value(head: Span, value: &HeaderFieldValue) -> Value { match value { SingleEmailAddress(address) => emailaddress_to_value(head, address), - MultipleEmailAddresses(addresses) => Value::List { - vals: addresses + MultipleEmailAddresses(addresses) => Value::list( + addresses .iter() .map(|a| emailaddress_to_value(head, a)) .collect(), - span: head, - }, + head, + ), Unstructured(s) => Value::string(s, head), Empty => Value::nothing(head), } @@ -151,13 +140,7 @@ fn from_eml(input: &Value, body_preview: usize, head: Span) -> Result Result Result output.push(calendar_to_value(c, head)), - Err(e) => output.push(Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Err(e) => output.push(Value::error( + ShellError::UnsupportedInput( format!("input cannot be parsed as .ics ({e})"), "value originates from here".into(), head, span, - )), + ), span, - }), + )), } } - Ok(Value::List { - vals: output, - span: head, - }) + Ok(Value::list(output, head)) } pub fn examples() -> Vec { @@ -50,8 +47,8 @@ pub fn examples() -> Vec { END:VCALENDAR' | from ics" .into(), description: "Converts ics formatted string to table".into(), - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec![ "properties".to_string(), "events".to_string(), @@ -62,38 +59,17 @@ pub fn examples() -> Vec { "timezones".to_string(), ], vals: vec![ - Value::List { - vals: vec![], - span: Span::test_data(), - }, - Value::List { - vals: vec![], - span: Span::test_data(), - }, - Value::List { - vals: vec![], - span: Span::test_data(), - }, - Value::List { - vals: vec![], - span: Span::test_data(), - }, - Value::List { - vals: vec![], - span: Span::test_data(), - }, - Value::List { - vals: vec![], - span: Span::test_data(), - }, - Value::List { - vals: vec![], - span: Span::test_data(), - }, + Value::list(vec![], Span::test_data()), + Value::list(vec![], Span::test_data()), + Value::list(vec![], Span::test_data()), + Value::list(vec![], Span::test_data()), + Value::list(vec![], Span::test_data()), + Value::list(vec![], Span::test_data()), + Value::list(vec![], Span::test_data()), ], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } @@ -113,8 +89,8 @@ fn calendar_to_value(calendar: IcalCalendar, span: Span) -> Value { } fn events_to_value(events: Vec, span: Span) -> Value { - Value::List { - vals: events + Value::list( + events .into_iter() .map(|event| { Value::record( @@ -127,12 +103,12 @@ fn events_to_value(events: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn alarms_to_value(alarms: Vec, span: Span) -> Value { - Value::List { - vals: alarms + Value::list( + alarms .into_iter() .map(|alarm| { Value::record( @@ -142,12 +118,12 @@ fn alarms_to_value(alarms: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn todos_to_value(todos: Vec, span: Span) -> Value { - Value::List { - vals: todos + Value::list( + todos .into_iter() .map(|todo| { Value::record( @@ -160,12 +136,12 @@ fn todos_to_value(todos: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn journals_to_value(journals: Vec, span: Span) -> Value { - Value::List { - vals: journals + Value::list( + journals .into_iter() .map(|journal| { Value::record( @@ -175,12 +151,12 @@ fn journals_to_value(journals: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn free_busys_to_value(free_busys: Vec, span: Span) -> Value { - Value::List { - vals: free_busys + Value::list( + free_busys .into_iter() .map(|free_busy| { Value::record( @@ -190,12 +166,12 @@ fn free_busys_to_value(free_busys: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn timezones_to_value(timezones: Vec, span: Span) -> Value { - Value::List { - vals: timezones + Value::list( + timezones .into_iter() .map(|timezone| { Value::record( @@ -208,12 +184,12 @@ fn timezones_to_value(timezones: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn timezone_transitions_to_value(transitions: Vec, span: Span) -> Value { - Value::List { - vals: transitions + Value::list( + transitions .into_iter() .map(|transition| { Value::record( @@ -223,20 +199,17 @@ fn timezone_transitions_to_value(transitions: Vec, span: }) .collect::>(), span, - } + ) } fn properties_to_value(properties: Vec, span: Span) -> Value { - Value::List { - vals: properties + Value::list( + properties .into_iter() .map(|prop| { - let name = Value::String { - val: prop.name, - span, - }; + let name = Value::string(prop.name, span); let value = match prop.value { - Some(val) => Value::String { val, span }, + Some(val) => Value::string(val, span), None => Value::nothing(span), }; let params = match prop.params { @@ -255,7 +228,7 @@ fn properties_to_value(properties: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn params_to_value(params: Vec<(String, Vec)>, span: Span) -> Value { @@ -266,7 +239,7 @@ fn params_to_value(params: Vec<(String, Vec)>, span: Span) -> Value { .into_iter() .map(|val| Value::string(val, span)) .collect(); - let values = Value::List { vals: values, span }; + let values = Value::list(values, span); row.insert(param_name, values); } diff --git a/crates/nu_plugin_formats/src/from/vcf.rs b/crates/nu_plugin_formats/src/from/vcf.rs index 8f3bdb6b3..c3302ce1b 100644 --- a/crates/nu_plugin_formats/src/from/vcf.rs +++ b/crates/nu_plugin_formats/src/from/vcf.rs @@ -23,22 +23,19 @@ pub fn from_vcf_call(call: &EvaluatedCall, input: &Value) -> Result contact_to_value(c, head), - Err(e) => Value::Error { - error: Box::new(ShellError::UnsupportedInput( + Err(e) => Value::error( + ShellError::UnsupportedInput( format!("input cannot be parsed as .vcf ({e})"), "value originates from here".into(), head, span, - )), + ), span, - }, + ), }); let collected: Vec<_> = iter.collect(); - Ok(Value::List { - vals: collected, - span: head, - }) + Ok(Value::list(collected, head)) } pub fn examples() -> Vec { @@ -50,11 +47,11 @@ EMAIL:foo@bar.com END:VCARD' | from vcf" .into(), description: "Converts ics formatted string to table".into(), - result: Some(Value::List { - vals: vec![Value::test_record(Record { + result: Some(Value::list( + vec![Value::test_record(Record { cols: vec!["properties".to_string()], - vals: vec![Value::List { - vals: vec![ + vals: vec![Value::list( + vec![ Value::test_record(Record { cols: vec![ "name".to_string(), @@ -64,9 +61,7 @@ END:VCARD' | from vcf" vals: vec![ Value::test_string("N"), Value::test_string("Foo"), - Value::Nothing { - span: Span::test_data(), - }, + Value::nothing(Span::test_data()), ], }), Value::test_record(Record { @@ -78,9 +73,7 @@ END:VCARD' | from vcf" vals: vec![ Value::test_string("FN"), Value::test_string("Bar"), - Value::Nothing { - span: Span::test_data(), - }, + Value::nothing(Span::test_data()), ], }), Value::test_record(Record { @@ -92,17 +85,15 @@ END:VCARD' | from vcf" vals: vec![ Value::test_string("EMAIL"), Value::test_string("foo@bar.com"), - Value::Nothing { - span: Span::test_data(), - }, + Value::nothing(Span::test_data()), ], }), ], - span: Span::test_data(), - }], + Span::test_data(), + )], })], - span: Span::test_data(), - }), + Span::test_data(), + )), }] } @@ -114,21 +105,18 @@ fn contact_to_value(contact: VcardContact, span: Span) -> Value { } fn properties_to_value(properties: Vec, span: Span) -> Value { - Value::List { - vals: properties + Value::list( + properties .into_iter() .map(|prop| { - let name = Value::String { - val: prop.name, - span, - }; + let name = Value::string(prop.name, span); let value = match prop.value { - Some(val) => Value::String { val, span }, - None => Value::Nothing { span }, + Some(val) => Value::string(val, span), + None => Value::nothing(span), }; let params = match prop.params { Some(param_list) => params_to_value(param_list, span), - None => Value::Nothing { span }, + None => Value::nothing(span), }; Value::record( @@ -142,7 +130,7 @@ fn properties_to_value(properties: Vec, span: Span) -> Value { }) .collect::>(), span, - } + ) } fn params_to_value(params: Vec<(String, Vec)>, span: Span) -> Value { @@ -153,7 +141,7 @@ fn params_to_value(params: Vec<(String, Vec)>, span: Span) -> Value { .into_iter() .map(|val| Value::string(val, span)) .collect(); - let values = Value::List { vals: values, span }; + let values = Value::list(values, span); row.insert(param_name, values); } diff --git a/crates/nu_plugin_gstat/src/nu/mod.rs b/crates/nu_plugin_gstat/src/nu/mod.rs index 7b737d850..504bffbbe 100644 --- a/crates/nu_plugin_gstat/src/nu/mod.rs +++ b/crates/nu_plugin_gstat/src/nu/mod.rs @@ -17,7 +17,7 @@ impl Plugin for GStat { input: &Value, ) -> Result { if name != "gstat" { - return Ok(Value::Nothing { span: call.head }); + return Ok(Value::nothing(call.head)); } let repo_path: Option> = call.opt(0)?; diff --git a/crates/nu_plugin_inc/src/inc.rs b/crates/nu_plugin_inc/src/inc.rs index d6cd56c02..7bfa92cf2 100644 --- a/crates/nu_plugin_inc/src/inc.rs +++ b/crates/nu_plugin_inc/src/inc.rs @@ -116,7 +116,7 @@ impl Inc { pub fn inc_value(&self, head: Span, value: &Value) -> Result { match value { - Value::Int { val, span } => Ok(Value::int(val + 1, *span)), + Value::Int { val, .. } => Ok(Value::int(val + 1, head)), Value::String { val, .. } => Ok(self.apply(val, head)), x => { let msg = x.as_string().map_err(|e| LabeledError { diff --git a/crates/nu_plugin_inc/src/nu/mod.rs b/crates/nu_plugin_inc/src/nu/mod.rs index 1c66c5c13..597e57e19 100644 --- a/crates/nu_plugin_inc/src/nu/mod.rs +++ b/crates/nu_plugin_inc/src/nu/mod.rs @@ -32,7 +32,7 @@ impl Plugin for Inc { input: &Value, ) -> Result { if name != "inc" { - return Ok(Value::Nothing { span: call.head }); + return Ok(Value::nothing(call.head)); } let cell_path: Option = call.opt(0)?; diff --git a/crates/nu_plugin_query/src/query_json.rs b/crates/nu_plugin_query/src/query_json.rs index b36f23873..52af64c47 100644 --- a/crates/nu_plugin_query/src/query_json.rs +++ b/crates/nu_plugin_query/src/query_json.rs @@ -79,7 +79,7 @@ fn convert_gjson_value_to_nu_value(v: &gjValue, span: Span) -> Value { true }); - Value::List { vals, span } + Value::list(vals, span) } gjson::Kind::Null => Value::nothing(span), gjson::Kind::False => Value::bool(false, span), diff --git a/crates/nu_plugin_query/src/query_web.rs b/crates/nu_plugin_query/src/query_web.rs index 6b1d39850..b1fdc1e4d 100644 --- a/crates/nu_plugin_query/src/query_web.rs +++ b/crates/nu_plugin_query/src/query_web.rs @@ -59,12 +59,13 @@ pub fn parse_selector_params(call: &EvaluatedCall, input: &Value) -> Result Ok(begin_selector_query(val.to_string(), selector, *span)), + Value::String { val, .. } => Ok(begin_selector_query(val.to_string(), selector, span)), _ => Err(LabeledError { label: "requires text input".to_string(), msg: "Expected text from pipeline".to_string(), - span: Some(input.span()), + span: Some(span), }), } } @@ -140,7 +141,7 @@ pub fn retrieve_tables( .map(move |table| retrieve_table(table, columns, span)) .collect(); - Value::List { vals, span } + Value::list(vals, span) } fn retrieve_table(mut table: WebTable, columns: &Value, span: Span) -> Value { @@ -211,10 +212,7 @@ fn retrieve_table(mut table: WebTable, columns: &Value, span: Span) -> Value { } // table_out - Value::List { - vals: table_out, - span, - } + Value::list(table_out, span) } fn execute_selector_query_with_attribute( @@ -235,7 +233,7 @@ fn execute_selector_query_with_attribute( ) }) .collect(); - Value::List { vals, span } + Value::list(vals, span) } fn execute_selector_query( @@ -265,7 +263,7 @@ fn execute_selector_query( .collect(), }; - Value::List { vals, span } + Value::list(vals, span) } pub fn css(selector: &str, inspect: bool) -> ScraperSelector { diff --git a/crates/nu_plugin_query/src/query_xml.rs b/crates/nu_plugin_query/src/query_xml.rs index 0fe897467..813c51521 100644 --- a/crates/nu_plugin_query/src/query_xml.rs +++ b/crates/nu_plugin_query/src/query_xml.rs @@ -79,10 +79,7 @@ pub fn execute_xpath_query( records.push(Value::record(record! { k => v }, call.head)) } - Ok(Value::List { - vals: records, - span: call.head, - }) + Ok(Value::list(records, call.head)) } Err(_) => Err(LabeledError { label: "xpath query error".to_string(), @@ -135,13 +132,13 @@ mod tests { }; let actual = query("", &call, &text, Some(spanned_str)).expect("test should not fail"); - let expected = Value::List { - vals: vec![Value::test_record(Record { + let expected = Value::list( + vec![Value::test_record(Record { cols: vec!["count(//a/*[posit...".to_string()], vals: vec![Value::test_float(1.0)], })], - span: Span::test_data(), - }; + Span::test_data(), + ); assert_eq!(actual, expected); } @@ -165,13 +162,13 @@ mod tests { }; let actual = query("", &call, &text, Some(spanned_str)).expect("test should not fail"); - let expected = Value::List { - vals: vec![Value::test_record(Record { + let expected = Value::list( + vec![Value::test_record(Record { cols: vec!["count(//*[contain...".to_string()], vals: vec![Value::test_float(1.0)], })], - span: Span::test_data(), - }; + Span::test_data(), + ); assert_eq!(actual, expected); } diff --git a/src/command.rs b/src/command.rs index a53565ef6..3172a8048 100644 --- a/src/command.rs +++ b/src/command.rs @@ -384,10 +384,10 @@ impl Command for Nu { call: &Call, _input: PipelineData, ) -> Result { - Ok(Value::String { - val: get_full_help(&Nu.signature(), &Nu.examples(), engine_state, stack, true), - span: call.head, - } + Ok(Value::string( + get_full_help(&Nu.signature(), &Nu.examples(), engine_state, stack, true), + call.head, + ) .into_pipeline_data()) } diff --git a/src/main.rs b/src/main.rs index 238c0b768..b2a95243d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -164,13 +164,10 @@ fn main() -> Result<()> { let vals: Vec<_> = include_path .item .split('\x1e') // \x1e is the record separator character (a character that is unlikely to appear in a path) - .map(|x| Value::String { - val: x.trim().to_string(), - span, - }) + .map(|x| Value::string(x.trim().to_string(), span)) .collect(); - engine_state.add_env_var("NU_LIB_DIRS".into(), Value::List { vals, span }); + engine_state.add_env_var("NU_LIB_DIRS".into(), Value::list(vals, span)); } start_time = std::time::Instant::now();