mirror of
https://github.com/nushell/nushell.git
synced 2024-11-21 16:03:19 +01:00
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:
parent
af79eb2943
commit
6cdfee3573
@ -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) {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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,
|
||||
)
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -84,8 +84,9 @@ pub fn eval_hook(
|
||||
optional: false,
|
||||
};
|
||||
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::String { val, span } => {
|
||||
Value::String { val, .. } => {
|
||||
let (block, delta, vars) = {
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
|
||||
@ -113,7 +114,7 @@ pub fn eval_hook(
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"valid source code".into(),
|
||||
"source code with syntax errors".into(),
|
||||
*span,
|
||||
span,
|
||||
));
|
||||
}
|
||||
|
||||
@ -161,64 +162,56 @@ pub fn eval_hook(
|
||||
}
|
||||
}
|
||||
Value::Record { .. } => {
|
||||
let do_run_hook =
|
||||
if let Ok(condition) = value.clone().follow_cell_path(&[condition_path], false) {
|
||||
match condition {
|
||||
Value::Block {
|
||||
val: block_id,
|
||||
span: block_span,
|
||||
..
|
||||
}
|
||||
| Value::Closure {
|
||||
val: block_id,
|
||||
span: block_span,
|
||||
..
|
||||
} => {
|
||||
match run_hook_block(
|
||||
engine_state,
|
||||
stack,
|
||||
block_id,
|
||||
None,
|
||||
arguments.clone(),
|
||||
block_span,
|
||||
) {
|
||||
Ok(pipeline_data) => {
|
||||
if let PipelineData::Value(Value::Bool { val, .. }, ..) =
|
||||
pipeline_data
|
||||
{
|
||||
val
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"boolean output".to_string(),
|
||||
"other PipelineData variant".to_string(),
|
||||
block_span,
|
||||
));
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
let do_run_hook = if let Ok(condition) =
|
||||
value.clone().follow_cell_path(&[condition_path], false)
|
||||
{
|
||||
let other_span = condition.span();
|
||||
match condition {
|
||||
Value::Block { val: block_id, .. } | Value::Closure { val: block_id, .. } => {
|
||||
match run_hook_block(
|
||||
engine_state,
|
||||
stack,
|
||||
block_id,
|
||||
None,
|
||||
arguments.clone(),
|
||||
other_span,
|
||||
) {
|
||||
Ok(pipeline_data) => {
|
||||
if let PipelineData::Value(Value::Bool { val, .. }, ..) =
|
||||
pipeline_data
|
||||
{
|
||||
val
|
||||
} else {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"boolean output".to_string(),
|
||||
"other PipelineData variant".to_string(),
|
||||
other_span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
other => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"block".to_string(),
|
||||
format!("{}", other.get_type()),
|
||||
other.span(),
|
||||
));
|
||||
Err(err) => {
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// always run the hook
|
||||
true
|
||||
};
|
||||
other => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"block".to_string(),
|
||||
format!("{}", other.get_type()),
|
||||
other_span,
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// always run the hook
|
||||
true
|
||||
};
|
||||
|
||||
if do_run_hook {
|
||||
match value.clone().follow_cell_path(&[code_path], false)? {
|
||||
Value::String {
|
||||
val,
|
||||
span: source_span,
|
||||
} => {
|
||||
let follow = value.clone().follow_cell_path(&[code_path], false)?;
|
||||
let source_span = follow.span();
|
||||
match follow {
|
||||
Value::String { val, .. } => {
|
||||
let (block, delta, vars) = {
|
||||
let mut working_set = StateWorkingSet::new(engine_state);
|
||||
|
||||
@ -277,71 +270,41 @@ pub fn eval_hook(
|
||||
stack.remove_var(*var_id);
|
||||
}
|
||||
}
|
||||
Value::Block {
|
||||
val: block_id,
|
||||
span: block_span,
|
||||
..
|
||||
} => {
|
||||
Value::Block { val: block_id, .. } => {
|
||||
run_hook_block(
|
||||
engine_state,
|
||||
stack,
|
||||
block_id,
|
||||
input,
|
||||
arguments,
|
||||
block_span,
|
||||
source_span,
|
||||
)?;
|
||||
}
|
||||
Value::Closure {
|
||||
val: block_id,
|
||||
span: block_span,
|
||||
..
|
||||
} => {
|
||||
Value::Closure { val: block_id, .. } => {
|
||||
run_hook_block(
|
||||
engine_state,
|
||||
stack,
|
||||
block_id,
|
||||
input,
|
||||
arguments,
|
||||
block_span,
|
||||
source_span,
|
||||
)?;
|
||||
}
|
||||
other => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
"block or string".to_string(),
|
||||
format!("{}", other.get_type()),
|
||||
other.span(),
|
||||
source_span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Value::Block {
|
||||
val: block_id,
|
||||
span: block_span,
|
||||
..
|
||||
} => {
|
||||
output = run_hook_block(
|
||||
engine_state,
|
||||
stack,
|
||||
*block_id,
|
||||
input,
|
||||
arguments,
|
||||
*block_span,
|
||||
)?;
|
||||
Value::Block { val: block_id, .. } => {
|
||||
output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?;
|
||||
}
|
||||
Value::Closure {
|
||||
val: block_id,
|
||||
span: block_span,
|
||||
..
|
||||
} => {
|
||||
output = run_hook_block(
|
||||
engine_state,
|
||||
stack,
|
||||
*block_id,
|
||||
input,
|
||||
arguments,
|
||||
*block_span,
|
||||
)?;
|
||||
Value::Closure { val: block_id, .. } => {
|
||||
output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?;
|
||||
}
|
||||
other => {
|
||||
return Err(ShellError::UnsupportedConfigValue(
|
||||
|
@ -76,10 +76,7 @@ where
|
||||
}),
|
||||
);
|
||||
if let Err(error) = r {
|
||||
return Value::Error {
|
||||
error: Box::new(error),
|
||||
span,
|
||||
};
|
||||
return Value::error(error, span);
|
||||
}
|
||||
}
|
||||
v
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
})
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -120,30 +120,30 @@ fn command(
|
||||
let quantiles = quantiles.map(|values| {
|
||||
values
|
||||
.iter()
|
||||
.map(|value| match value {
|
||||
Value::Float { val, span } => {
|
||||
if (&0.0..=&1.0).contains(&val) {
|
||||
Ok(*val)
|
||||
} else {
|
||||
Err(ShellError::GenericError(
|
||||
"Incorrect value for quantile".to_string(),
|
||||
"value should be between 0 and 1".to_string(),
|
||||
Some(*span),
|
||||
None,
|
||||
Vec::new(),
|
||||
))
|
||||
.map(|value| {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Float { val, .. } => {
|
||||
if (&0.0..=&1.0).contains(&val) {
|
||||
Ok(*val)
|
||||
} else {
|
||||
Err(ShellError::GenericError(
|
||||
"Incorrect value for quantile".to_string(),
|
||||
"value should be between 0 and 1".to_string(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
Value::Error { error, .. } => Err(*error.clone()),
|
||||
_ => {
|
||||
let span = value.span();
|
||||
Err(ShellError::GenericError(
|
||||
Value::Error { error, .. } => Err(*error.clone()),
|
||||
_ => Err(ShellError::GenericError(
|
||||
"Incorrect value for quantile".to_string(),
|
||||
"value should be a float".to_string(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
))
|
||||
)),
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<f64>, ShellError>>()
|
||||
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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,
|
||||
))
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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)?;
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -102,18 +102,21 @@ impl Command for LazyFillNA {
|
||||
let column_name = column.name().to_string();
|
||||
let values = column
|
||||
.into_iter()
|
||||
.map(|value| match value {
|
||||
Value::Float { val, .. } => {
|
||||
if val.is_nan() {
|
||||
fill.clone()
|
||||
} else {
|
||||
value
|
||||
.map(|value| {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Float { val, .. } => {
|
||||
if val.is_nan() {
|
||||
fill.clone()
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
Value::List { vals, .. } => {
|
||||
NuDataFrame::fill_list_nan(vals, span, fill.clone())
|
||||
}
|
||||
_ => value,
|
||||
}
|
||||
Value::List { vals, span } => {
|
||||
NuDataFrame::fill_list_nan(vals, span, fill.clone())
|
||||
}
|
||||
_ => value,
|
||||
})
|
||||
.collect::<Vec<Value>>();
|
||||
Column::new(column_name, values)
|
||||
|
@ -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
|
||||
|
@ -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)?;
|
||||
|
@ -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");
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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(),
|
||||
)),
|
||||
|
@ -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(),
|
||||
)),
|
||||
|
@ -267,29 +267,37 @@ pub(super) fn compute_series_single_value(
|
||||
rhs_span: right.span(),
|
||||
}),
|
||||
},
|
||||
Operator::Math(Math::Divide) => match &right {
|
||||
Value::Int { val, span } => {
|
||||
if *val == 0 {
|
||||
Err(ShellError::DivisionByZero { span: *span })
|
||||
} else {
|
||||
compute_series_i64(&lhs, *val, <ChunkedArray<Int64Type>>::div, lhs_span)
|
||||
Operator::Math(Math::Divide) => {
|
||||
let span = right.span();
|
||||
match &right {
|
||||
Value::Int { val, .. } => {
|
||||
if *val == 0 {
|
||||
Err(ShellError::DivisionByZero { span })
|
||||
} else {
|
||||
compute_series_i64(&lhs, *val, <ChunkedArray<Int64Type>>::div, lhs_span)
|
||||
}
|
||||
}
|
||||
}
|
||||
Value::Float { val, span } => {
|
||||
if val.is_zero() {
|
||||
Err(ShellError::DivisionByZero { span: *span })
|
||||
} else {
|
||||
compute_series_decimal(&lhs, *val, <ChunkedArray<Float64Type>>::div, lhs_span)
|
||||
Value::Float { val, .. } => {
|
||||
if val.is_zero() {
|
||||
Err(ShellError::DivisionByZero { span })
|
||||
} else {
|
||||
compute_series_decimal(
|
||||
&lhs,
|
||||
*val,
|
||||
<ChunkedArray<Float64Type>>::div,
|
||||
lhs_span,
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: operator.span,
|
||||
lhs_ty: left.get_type().to_string(),
|
||||
lhs_span: left.span(),
|
||||
rhs_ty: right.get_type().to_string(),
|
||||
rhs_span: right.span(),
|
||||
}),
|
||||
}
|
||||
_ => Err(ShellError::OperatorMismatch {
|
||||
op_span: operator.span,
|
||||
lhs_ty: left.get_type().to_string(),
|
||||
lhs_span: left.span(),
|
||||
rhs_ty: right.get_type().to_string(),
|
||||
rhs_span: right.span(),
|
||||
}),
|
||||
},
|
||||
}
|
||||
Operator::Comparison(Comparison::Equal) => match &right {
|
||||
Value::Int { val, .. } => compare_series_i64(&lhs, *val, ChunkedArray::equal, lhs_span),
|
||||
Value::Float { val, .. } => {
|
||||
|
@ -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(),
|
||||
|
@ -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 {
|
||||
|
@ -38,9 +38,7 @@ impl Display for DataFrameValue {
|
||||
|
||||
impl Default for DataFrameValue {
|
||||
fn default() -> Self {
|
||||
Self(Value::Nothing {
|
||||
span: Span::unknown(),
|
||||
})
|
||||
Self(Value::nothing(Span::unknown()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,24 +109,15 @@ impl NuDataFrame {
|
||||
}
|
||||
|
||||
pub fn dataframe_into_value(dataframe: DataFrame, span: Span) -> Value {
|
||||
Value::CustomValue {
|
||||
val: Box::new(Self::new(false, dataframe)),
|
||||
span,
|
||||
}
|
||||
Value::custom_value(Box::new(Self::new(false, dataframe)), span)
|
||||
}
|
||||
|
||||
pub fn into_value(self, span: Span) -> Value {
|
||||
if self.from_lazy {
|
||||
let lazy = NuLazyFrame::from_dataframe(self);
|
||||
Value::CustomValue {
|
||||
val: Box::new(lazy),
|
||||
span,
|
||||
}
|
||||
Value::custom_value(Box::new(lazy), span)
|
||||
} else {
|
||||
Value::CustomValue {
|
||||
val: Box::new(self),
|
||||
span,
|
||||
}
|
||||
Value::custom_value(Box::new(self), span)
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,16 +196,19 @@ impl NuDataFrame {
|
||||
pub fn fill_list_nan(list: Vec<Value>, list_span: Span, fill: Value) -> Value {
|
||||
let newlist = list
|
||||
.into_iter()
|
||||
.map(|value| match value {
|
||||
Value::Float { val, .. } => {
|
||||
if val.is_nan() {
|
||||
fill.clone()
|
||||
} else {
|
||||
value
|
||||
.map(|value| {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::Float { val, .. } => {
|
||||
if val.is_nan() {
|
||||
fill.clone()
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
Value::List { vals, .. } => Self::fill_list_nan(vals, span, fill.clone()),
|
||||
_ => value,
|
||||
}
|
||||
Value::List { vals, span } => Self::fill_list_nan(vals, span, fill.clone()),
|
||||
_ => value,
|
||||
})
|
||||
.collect::<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,
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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(
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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,22 +82,21 @@ 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>() {
|
||||
Some(group) => Ok(Self {
|
||||
group_by: group.group_by.clone(),
|
||||
schema: group.schema.clone(),
|
||||
from_eager: group.from_eager,
|
||||
}),
|
||||
None => Err(ShellError::CantConvert {
|
||||
to_type: "lazy groupby".into(),
|
||||
from_type: "custom value".into(),
|
||||
span,
|
||||
help: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
Value::CustomValue { val, .. } => match val.as_any().downcast_ref::<NuLazyGroupBy>() {
|
||||
Some(group) => Ok(Self {
|
||||
group_by: group.group_by.clone(),
|
||||
schema: group.schema.clone(),
|
||||
from_eager: group.from_eager,
|
||||
}),
|
||||
None => Err(ShellError::CantConvert {
|
||||
to_type: "lazy groupby".into(),
|
||||
from_type: "custom value".into(),
|
||||
span,
|
||||
help: None,
|
||||
}),
|
||||
},
|
||||
x => Err(ShellError::CantConvert {
|
||||
to_type: "lazy groupby".into(),
|
||||
from_type: x.get_type().to_string(),
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -25,18 +25,21 @@ pub(crate) fn convert_columns(
|
||||
|
||||
let res = columns
|
||||
.into_iter()
|
||||
.map(|value| match value {
|
||||
Value::String { val, span } => {
|
||||
col_span = span_join(&[col_span, span]);
|
||||
Ok(Spanned { item: val, span })
|
||||
.map(|value| {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::String { val, .. } => {
|
||||
col_span = span_join(&[col_span, span]);
|
||||
Ok(Spanned { item: val, span })
|
||||
}
|
||||
_ => Err(ShellError::GenericError(
|
||||
"Incorrect column format".into(),
|
||||
"Only string as column name".into(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
}
|
||||
_ => Err(ShellError::GenericError(
|
||||
"Incorrect column format".into(),
|
||||
"Only string as column name".into(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
})
|
||||
.collect::<Result<Vec<Spanned<String>>, _>>()?;
|
||||
|
||||
@ -65,18 +68,21 @@ pub(crate) fn convert_columns_string(
|
||||
|
||||
let res = columns
|
||||
.into_iter()
|
||||
.map(|value| match value {
|
||||
Value::String { val, span } => {
|
||||
col_span = span_join(&[col_span, span]);
|
||||
Ok(val)
|
||||
.map(|value| {
|
||||
let span = value.span();
|
||||
match value {
|
||||
Value::String { val, .. } => {
|
||||
col_span = span_join(&[col_span, span]);
|
||||
Ok(val)
|
||||
}
|
||||
_ => Err(ShellError::GenericError(
|
||||
"Incorrect column format".into(),
|
||||
"Only string as column name".into(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
}
|
||||
_ => Err(ShellError::GenericError(
|
||||
"Incorrect column format".into(),
|
||||
"Only string as column name".into(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
)),
|
||||
})
|
||||
.collect::<Result<Vec<String>, _>>()?;
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
}]
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
}]
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,7 @@ impl Command for Rotate {
|
||||
Example {
|
||||
description: "Rotate a record clockwise, producing a table (like `transpose` but with column order reversed)",
|
||||
example: "{a:1, b:2} | rotate",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["column0".to_string(), "column1".to_string()],
|
||||
vals: vec![Value::test_int(1), Value::test_string("a")],
|
||||
@ -49,14 +48,14 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_int(2), Value::test_string("b")],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate 2x3 table clockwise",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | rotate",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec![
|
||||
"column0".to_string(),
|
||||
@ -86,14 +85,14 @@ impl Command for Rotate {
|
||||
],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table clockwise and change columns names",
|
||||
example: "[[a b]; [1 2]] | rotate col_a col_b",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["col_a".to_string(), "col_b".to_string()],
|
||||
vals: vec![Value::test_int(1), Value::test_string("a")],
|
||||
@ -103,14 +102,14 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_int(2), Value::test_string("b")],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table counter clockwise",
|
||||
example: "[[a b]; [1 2]] | rotate --ccw",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["column0".to_string(), "column1".to_string()],
|
||||
vals: vec![Value::test_string("b"), Value::test_int(2)],
|
||||
@ -120,14 +119,14 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_string("a"), Value::test_int(1)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table counter-clockwise",
|
||||
example: "[[a b]; [1 2] [3 4] [5 6]] | rotate --ccw",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec![
|
||||
"column0".to_string(),
|
||||
@ -157,14 +156,14 @@ impl Command for Rotate {
|
||||
],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
description: "Rotate table counter-clockwise and change columns names",
|
||||
example: "[[a b]; [1 2]] | rotate --ccw col_a col_b",
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
result: Some(Value::list(
|
||||
vec![
|
||||
Value::test_record(Record {
|
||||
cols: vec!["col_a".to_string(), "col_b".to_string()],
|
||||
vals: vec![Value::test_string("b"), Value::test_int(2)],
|
||||
@ -174,8 +173,8 @@ impl Command for Rotate {
|
||||
vals: vec![Value::test_string("a"), Value::test_int(1)],
|
||||
}),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
Span::test_data(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -213,6 +212,7 @@ pub fn rotate(
|
||||
|
||||
if !values.is_empty() {
|
||||
for val in values.into_iter() {
|
||||
let span = val.span();
|
||||
match val {
|
||||
Value::Record { val: record, .. } => {
|
||||
old_column_names = record.cols;
|
||||
@ -226,9 +226,9 @@ pub fn rotate(
|
||||
new_values.push(v);
|
||||
}
|
||||
}
|
||||
Value::String { val, span } => {
|
||||
Value::String { val, .. } => {
|
||||
not_a_record = true;
|
||||
new_values.push(Value::String { val, span })
|
||||
new_values.push(Value::string(val, span))
|
||||
}
|
||||
x => {
|
||||
not_a_record = true;
|
||||
@ -273,16 +273,16 @@ pub fn rotate(
|
||||
}
|
||||
|
||||
if not_a_record {
|
||||
return Ok(Value::List {
|
||||
vals: vec![Value::record(
|
||||
return Ok(Value::list(
|
||||
vec![Value::record(
|
||||
Record {
|
||||
cols: new_column_names,
|
||||
vals: new_values,
|
||||
},
|
||||
call.head,
|
||||
)],
|
||||
span: call.head,
|
||||
}
|
||||
call.head,
|
||||
)
|
||||
.into_pipeline_data()
|
||||
.set_metadata(metadata));
|
||||
}
|
||||
@ -332,12 +332,9 @@ pub fn rotate(
|
||||
))
|
||||
}
|
||||
|
||||
Ok(Value::List {
|
||||
vals: final_values,
|
||||
span: call.head,
|
||||
}
|
||||
.into_pipeline_data()
|
||||
.set_metadata(metadata))
|
||||
Ok(Value::list(final_values, call.head)
|
||||
.into_pipeline_data()
|
||||
.set_metadata(metadata))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,13 +288,13 @@ fn to_html(
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
return Ok(Value::List {
|
||||
vals: result,
|
||||
span: head,
|
||||
}
|
||||
.into_pipeline_data_with_metadata(Box::new(PipelineMetadata {
|
||||
data_source: DataSource::HtmlThemes,
|
||||
})));
|
||||
return Ok(
|
||||
Value::list(result, head).into_pipeline_data_with_metadata(Box::new(
|
||||
PipelineMetadata {
|
||||
data_source: DataSource::HtmlThemes,
|
||||
},
|
||||
)),
|
||||
);
|
||||
} else {
|
||||
let theme_span = match &theme {
|
||||
Some(v) => v.span,
|
||||
@ -403,7 +403,8 @@ fn html_table(table: Vec<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);
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user