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
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use std testing; testing run-tests --path
crates/nu-std"` to run the tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->

---------

Co-authored-by: Darren Schroeder <343840+fdncred@users.noreply.github.com>
Co-authored-by: WindSoilder <windsoilder@outlook.com>
This commit is contained in:
JT 2023-09-04 02:27:29 +12:00 committed by GitHub
parent af79eb2943
commit 6cdfee3573
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
372 changed files with 5811 additions and 7448 deletions

View File

@ -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) {

View File

@ -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())
}
}
}

View File

@ -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::<i64>() {
@ -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::<i64>() {
@ -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 {

View File

@ -41,16 +41,16 @@ For more information on input and keybindings, check:
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
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())
}
}

View File

@ -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())
}
}

View File

@ -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())
}
}

View File

@ -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);

View File

@ -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<Vec<u8>>) -> 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<Vec<u8>>) -> 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<Vec<u8>>) -> 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<Vec<u8>>) -> Value {
}
// Current sublevel value not found
return Value::Nothing {
span: Span::unknown(),
};
return Value::nothing(span);
}
_ => return val,
}

View File

@ -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,
)

View File

@ -131,8 +131,9 @@ fn add_menu(
stack: &Stack,
config: &Config,
) -> Result<Reedline, ShellError> {
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<Reedline, ShellError> {
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<Option<ReedlineEvent>, 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<Option<ReedlineEvent>,
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();

View File

@ -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()

View File

@ -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,

View File

@ -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
)

View File

@ -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,26 +162,19 @@ pub fn eval_hook(
}
}
Value::Record { .. } => {
let do_run_hook =
if let Ok(condition) = value.clone().follow_cell_path(&[condition_path], false) {
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,
span: block_span,
..
}
| Value::Closure {
val: block_id,
span: block_span,
..
} => {
Value::Block { val: block_id, .. } | Value::Closure { val: block_id, .. } => {
match run_hook_block(
engine_state,
stack,
block_id,
None,
arguments.clone(),
block_span,
other_span,
) {
Ok(pipeline_data) => {
if let PipelineData::Value(Value::Bool { val, .. }, ..) =
@ -191,7 +185,7 @@ pub fn eval_hook(
return Err(ShellError::UnsupportedConfigValue(
"boolean output".to_string(),
"other PipelineData variant".to_string(),
block_span,
other_span,
));
}
}
@ -204,7 +198,7 @@ pub fn eval_hook(
return Err(ShellError::UnsupportedConfigValue(
"block".to_string(),
format!("{}", other.get_type()),
other.span(),
other_span,
));
}
}
@ -214,11 +208,10 @@ pub fn eval_hook(
};
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(

View File

@ -76,10 +76,7 @@ where
}),
);
if let Err(error) = r {
return Value::Error {
error: Box::new(error),
span,
};
return Value::error(error, span);
}
}
v

View File

@ -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))
}

View File

@ -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)
})

View File

@ -66,10 +66,7 @@ impl Command for ListDF {
})
.collect::<Vec<Value>>();
let list = Value::List {
vals,
span: call.head,
};
let list = Value::list(vals, call.head);
Ok(list.into_pipeline_data())
}

View File

@ -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))
}

View File

@ -120,30 +120,30 @@ fn command(
let quantiles = quantiles.map(|values| {
values
.iter()
.map(|value| match value {
Value::Float { val, span } => {
.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),
Some(span),
None,
Vec::new(),
))
}
}
Value::Error { error, .. } => Err(*error.clone()),
_ => {
let span = value.span();
Err(ShellError::GenericError(
_ => Err(ShellError::GenericError(
"Incorrect value for quantile".to_string(),
"value should be a float".to_string(),
Some(span),
None,
Vec::new(),
))
)),
}
})
.collect::<Result<Vec<f64>, ShellError>>()

View File

@ -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,
))
}

View File

@ -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,
))
}

View File

@ -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,
))
}

View File

@ -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,
))
}

View File

@ -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))
}

View File

@ -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,
))
}

View File

@ -132,10 +132,7 @@ fn command_eager(
if NuExpression::can_downcast(&new_column) {
let vals: Vec<Value> = 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<PipelineData, ShellError> {
let vals: Vec<Value> = 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();

View File

@ -114,10 +114,7 @@ impl Command for LazyAggregate {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let vals: Vec<Value> = 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)?;

View File

@ -58,10 +58,7 @@ impl Command for LazyCollect {
) -> Result<PipelineData, ShellError> {
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))
}

View File

@ -102,7 +102,9 @@ impl Command for LazyFillNA {
let column_name = column.name().to_string();
let values = column
.into_iter()
.map(|value| match value {
.map(|value| {
let span = value.span();
match value {
Value::Float { val, .. } => {
if val.is_nan() {
fill.clone()
@ -110,10 +112,11 @@ impl Command for LazyFillNA {
value
}
}
Value::List { vals, span } => {
Value::List { vals, .. } => {
NuDataFrame::fill_list_nan(vals, span, fill.clone())
}
_ => value,
}
})
.collect::<Vec<Value>>();
Column::new(column_name, values)

View File

@ -113,10 +113,7 @@ impl Command for ToLazyGroupBy {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let vals: Vec<Value> = 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

View File

@ -55,10 +55,7 @@ impl Command for LazySelect {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let vals: Vec<Value> = 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)?;

View File

@ -105,10 +105,7 @@ impl Command for LazySortBy {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let vals: Vec<Value> = 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");

View File

@ -41,10 +41,7 @@ impl Command for ToLazyFrame {
) -> Result<PipelineData, ShellError> {
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))
}

View File

@ -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")

View File

@ -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(),
)),

View File

@ -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(),
)),

View File

@ -267,19 +267,26 @@ pub(super) fn compute_series_single_value(
rhs_span: right.span(),
}),
},
Operator::Math(Math::Divide) => match &right {
Value::Int { val, span } => {
Operator::Math(Math::Divide) => {
let span = right.span();
match &right {
Value::Int { val, .. } => {
if *val == 0 {
Err(ShellError::DivisionByZero { span: *span })
Err(ShellError::DivisionByZero { span })
} else {
compute_series_i64(&lhs, *val, <ChunkedArray<Int64Type>>::div, lhs_span)
}
}
Value::Float { val, span } => {
Value::Float { val, .. } => {
if val.is_zero() {
Err(ShellError::DivisionByZero { span: *span })
Err(ShellError::DivisionByZero { span })
} else {
compute_series_decimal(&lhs, *val, <ChunkedArray<Float64Type>>::div, lhs_span)
compute_series_decimal(
&lhs,
*val,
<ChunkedArray<Float64Type>>::div,
lhs_span,
)
}
}
_ => Err(ShellError::OperatorMismatch {
@ -289,7 +296,8 @@ pub(super) fn compute_series_single_value(
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, .. } => {

View File

@ -452,7 +452,7 @@ fn series_to_values(
) -> Result<Vec<Value>, 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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -850,10 +823,7 @@ fn series_to_values(
}
})
.unwrap_or(vec![]);
Value::List {
vals: sublist,
span,
}
Value::list(sublist, span)
})
.collect::<Vec<Value>>();
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::<FixedOffset>::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::<Vec<Value>>();
@ -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::<FixedOffset>::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::<Vec<Value>>();
@ -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::<Vec<Value>>();
@ -1043,20 +1004,14 @@ mod tests {
#[test]
fn test_parsed_column_string_list() -> Result<(), Box<dyn std::error::Error>> {
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(),

View File

@ -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<Value, ShellError> {
let vals = self.print(span)?;
Ok(Value::List { vals, span })
Ok(Value::list(vals, span))
}
fn as_any(&self) -> &dyn std::any::Any {

View File

@ -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,7 +196,9 @@ impl NuDataFrame {
pub fn fill_list_nan(list: Vec<Value>, list_span: Span, fill: Value) -> Value {
let newlist = list
.into_iter()
.map(|value| match value {
.map(|value| {
let span = value.span();
match value {
Value::Float { val, .. } => {
if val.is_nan() {
fill.clone()
@ -215,8 +206,9 @@ impl NuDataFrame {
value
}
}
Value::List { vals, span } => Self::fill_list_nan(vals, span, fill.clone()),
Value::List { vals, .. } => Self::fill_list_nan(vals, span, fill.clone()),
_ => value,
}
})
.collect::<Vec<Value>>();
Value::list(newlist, list_span)
@ -250,8 +242,9 @@ impl NuDataFrame {
}
pub fn get_df(value: Value) -> Result<Self, ShellError> {
let span = value.span();
match value {
Value::CustomValue { val, span } => match val.as_any().downcast_ref::<Self>() {
Value::CustomValue { val, .. } => match val.as_any().downcast_ref::<Self>() {
Some(df) => Ok(NuDataFrame {
df: df.df.clone(),
from_lazy: false,

View File

@ -20,15 +20,13 @@ impl NuDataFrame {
op_span: Span,
right: &Value,
) -> Result<Value, ShellError> {
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::<NuDataFrame>().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,
});
}

View File

@ -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<Value, ShellError> {
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::<NuExpression>().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() {

View File

@ -55,15 +55,13 @@ impl From<Expr> 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<Self, ShellError> {
let span = value.span();
match value {
Value::CustomValue { val, span } => match val.as_any().downcast_ref::<Self>() {
Value::CustomValue { val, .. } => match val.as_any().downcast_ref::<Self>() {
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<Value, ShellError> {
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<Value, ShellError> {
} => {
let by: Result<Vec<Value>, ShellError> =
by.iter().map(|b| expr_to_value(b, span)).collect();
let descending: Vec<Value> = descending
.iter()
.map(|r| Value::Bool { val: *r, span })
.collect();
let descending: Vec<Value> = 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<Value, ShellError> {
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(

View File

@ -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 {

View File

@ -90,15 +90,9 @@ impl NuLazyFrame {
pub fn into_value(self, span: Span) -> Result<Value, ShellError> {
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<Self, ShellError> {
let span = value.span();
match value {
Value::CustomValue { val, span } => match val.as_any().downcast_ref::<Self>() {
Value::CustomValue { val, .. } => match val.as_any().downcast_ref::<Self>() {
Some(expr) => Ok(Self {
lazy: expr.lazy.clone(),
from_eager: false,

View File

@ -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 {

View File

@ -74,10 +74,7 @@ impl From<LazyGroupBy> 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,9 +82,9 @@ impl NuLazyGroupBy {
}
pub fn try_from_value(value: Value) -> Result<Self, ShellError> {
let span = value.span();
match value {
Value::CustomValue { val, span } => {
match val.as_any().downcast_ref::<NuLazyGroupBy>() {
Value::CustomValue { val, .. } => match val.as_any().downcast_ref::<NuLazyGroupBy>() {
Some(group) => Ok(Self {
group_by: group.group_by.clone(),
schema: group.schema.clone(),
@ -99,8 +96,7 @@ impl NuLazyGroupBy {
span,
help: None,
}),
}
}
},
x => Err(ShellError::CantConvert {
to_type: "lazy groupby".into(),
from_type: x.get_type().to_string(),

View File

@ -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<Value, ShellError> {
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)
}

View File

@ -51,15 +51,13 @@ impl From<ChainedThen> 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<Self, ShellError> {
let span = value.span();
match value {
Value::CustomValue { val, span } => match val.as_any().downcast_ref::<Self>() {
Value::CustomValue { val, .. } => match val.as_any().downcast_ref::<Self>() {
Some(expr) => Ok(expr.clone()),
None => Err(ShellError::CantConvert {
to_type: "when expression".into(),

View File

@ -25,8 +25,10 @@ pub(crate) fn convert_columns(
let res = columns
.into_iter()
.map(|value| match value {
Value::String { 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 })
}
@ -37,6 +39,7 @@ pub(crate) fn convert_columns(
None,
Vec::new(),
)),
}
})
.collect::<Result<Vec<Spanned<String>>, _>>()?;
@ -65,8 +68,10 @@ pub(crate) fn convert_columns_string(
let res = columns
.into_iter()
.map(|value| match value {
Value::String { val, span } => {
.map(|value| {
let span = value.span();
match value {
Value::String { val, .. } => {
col_span = span_join(&[col_span, span]);
Ok(val)
}
@ -77,6 +82,7 @@ pub(crate) fn convert_columns_string(
None,
Vec::new(),
)),
}
})
.collect::<Result<Vec<String>, _>>()?;

View File

@ -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,
),
}
}

View File

@ -34,16 +34,16 @@ impl Command for Bits {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
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())
}
}

View File

@ -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 = <i64 as From<bool>>::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,
},
span,
),
}
}

View File

@ -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,
),
},
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
},
span,
),
}
}

View File

@ -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(),
)),
},
]
}

View File

@ -21,8 +21,9 @@ fn vertical_rotate_value(
by: Option<usize>,
direction: VerticalDirection,
) -> Result<Value, ShellError> {
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<Value, ShellError> {
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::<Result<Vec<Value>, ShellError>>()?;
Ok(Value::List { vals: values, span })
Ok(Value::list(values, span))
}
_ => Err(ShellError::TypeMismatch {
err_message: "record".to_string(),

View File

@ -36,16 +36,16 @@ impl Command for Roll {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
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())
}
}

View File

@ -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(),
)),
}]
}

View File

@ -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(),
)),
},
]
}

View File

@ -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(),
)),
},
]
}

View File

@ -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(),
)),
}]
}

View File

@ -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,10 +332,7 @@ pub fn rotate(
))
}
Ok(Value::List {
vals: final_values,
span: call.head,
}
Ok(Value::list(final_values, call.head)
.into_pipeline_data()
.set_metadata(metadata))
}

View File

@ -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),
}
}

View File

@ -288,13 +288,13 @@ fn to_html(
)
})
.collect();
return Ok(Value::List {
vals: result,
span: head,
}
.into_pipeline_data_with_metadata(Box::new(PipelineMetadata {
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<Value>, headers: Vec<String>, config: &Config) -> Strin
output_string.push_str("</tr></thead><tbody>");
for row in table {
if let Value::Record { span, .. } = row {
let span = row.span();
if let Value::Record { .. } = row {
output_string.push_str("<tr>");
for header in &headers {
let data = row.get_data_by_key(header);

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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,
),
}
}

View File

@ -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<Rgb>,
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(),
)
}
}
}

View File

@ -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<String>) -> 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(),
)
}
}
}

View File

@ -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(),
),
}
}

View File

@ -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(),
)),
},
]
}

View File

@ -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(),
)),
},
]
}

View File

@ -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(),
)),
},
]
}

View File

@ -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,
),
}
}

View File

@ -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(),
)),
},
]
}

View File

@ -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(),
)),
},
]
}

View File

@ -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(),
)),
},
]
}

View File

@ -34,16 +34,16 @@ impl Command for Str {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
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())
}
}

View File

@ -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(),
)),
},
]
}

View File

@ -106,11 +106,7 @@ fn run(call: &Call, input: PipelineData) -> Result<PipelineData, ShellError> {
}
};
Ok(Value::String {
val: description,
span: head,
}
.into_pipeline_data())
Ok(Value::string(description, head).into_pipeline_data())
}
#[cfg(test)]

View File

@ -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),
)
}
}

Some files were not shown because too many files have changed in this diff Show More