diff --git a/crates/nu-command/src/core_commands/do_.rs b/crates/nu-command/src/core_commands/do_.rs index 8bc4435d7c..09f6351b7a 100644 --- a/crates/nu-command/src/core_commands/do_.rs +++ b/crates/nu-command/src/core_commands/do_.rs @@ -39,7 +39,7 @@ impl Command for Do { let block = context.engine_state.get_block(block_id); - let state = context.enter_scope(); + let mut state = context.enter_scope(); let params: Vec<_> = block .signature diff --git a/crates/nu-command/src/core_commands/for_.rs b/crates/nu-command/src/core_commands/for_.rs index 5ce82dc60c..2a52296dfd 100644 --- a/crates/nu-command/src/core_commands/for_.rs +++ b/crates/nu-command/src/core_commands/for_.rs @@ -62,7 +62,7 @@ impl Command for For { .map(move |x| { let block = context.engine_state.get_block(block); - let state = context.enter_scope(); + let mut state = context.enter_scope(); state.add_var(var_id, x); @@ -75,6 +75,33 @@ impl Command for For { } }) .into_pipeline_data()), + Value::Range { val, span } => Ok(val + .into_range_iter()? + .map(move |x| { + let block = context.engine_state.get_block(block); + + let mut state = context.enter_scope(); + + state.add_var(var_id, x); + + match eval_block(&state, block, PipelineData::new()) { + Ok(value) => Value::List { + vals: value.collect(), + span, + }, + Err(error) => Value::Error { error }, + } + }) + .into_pipeline_data()), + x => { + let block = context.engine_state.get_block(block); + + let mut state = context.enter_scope(); + + state.add_var(var_id, x); + + eval_block(&state, block, PipelineData::new()) + } } } diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index 7293e9c9e0..d963fcb35c 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -1,7 +1,7 @@ use nu_engine::eval_block; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EvaluationContext}; -use nu_protocol::{Example, PipelineData, Signature, Span, SyntaxShape, Value}; +use nu_protocol::{Example, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value}; #[derive(Clone)] pub struct Each; @@ -65,186 +65,180 @@ impl Command for Each { let context = context.clone(); let span = call.head; - // match input { - // Value::Range { val, .. } => Ok(val - // .into_range_iter()? - // .enumerate() - // .map(move |(idx, x)| { - // let block = context.engine_state.get_block(block_id); + match input { + PipelineData::Value(Value::Range { val, .. }) => Ok(val + .into_range_iter()? + .enumerate() + .map(move |(idx, x)| { + let block = context.engine_state.get_block(block_id); - // let state = context.enter_scope(); + let state = context.enter_scope(); - // if let Some(var) = block.signature.get_positional(0) { - // if let Some(var_id) = &var.var_id { - // if numbered { - // state.add_var( - // *var_id, - // Value::Record { - // cols: vec!["index".into(), "item".into()], - // vals: vec![ - // Value::Int { - // val: idx as i64, - // span, - // }, - // x, - // ], - // span, - // }, - // ); - // } else { - // state.add_var(*var_id, x); - // } - // } - // } + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + if numbered { + state.add_var( + *var_id, + Value::Record { + cols: vec!["index".into(), "item".into()], + vals: vec![ + Value::Int { + val: idx as i64, + span, + }, + x, + ], + span, + }, + ); + } else { + state.add_var(*var_id, x); + } + } + } - // match eval_block(&state, block, Value::nothing()) { - // Ok(v) => v, - // Err(error) => Value::Error { error }, - // } - // }) - // .into_pipeline_data()), - // Value::List { vals: val, .. } => Ok(Value::Stream { - // stream: val - // .into_iter() - // .enumerate() - // .map(move |(idx, x)| { - // let engine_state = context.engine_state.borrow(); - // let block = engine_state.get_block(block_id); + match eval_block(&state, block, PipelineData::new()) { + Ok(v) => v, + Err(error) => Value::Error { error }.into_pipeline_data(), + } + }) + .flatten() + .into_pipeline_data()), + PipelineData::Value(Value::List { vals: val, .. }) => Ok(val + .into_iter() + .enumerate() + .map(move |(idx, x)| { + let block = context.engine_state.get_block(block_id); - // let state = context.enter_scope(); - // if let Some(var) = block.signature.get_positional(0) { - // if let Some(var_id) = &var.var_id { - // if numbered { - // state.add_var( - // *var_id, - // Value::Record { - // cols: vec!["index".into(), "item".into()], - // vals: vec![ - // Value::Int { - // val: idx as i64, - // span, - // }, - // x, - // ], - // span, - // }, - // ); - // } else { - // state.add_var(*var_id, x); - // } - // } - // } + let state = context.enter_scope(); + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + if numbered { + state.add_var( + *var_id, + Value::Record { + cols: vec!["index".into(), "item".into()], + vals: vec![ + Value::Int { + val: idx as i64, + span, + }, + x, + ], + span, + }, + ); + } else { + state.add_var(*var_id, x); + } + } + } - // match eval_block(&state, block, Value::nothing()) { - // Ok(v) => v, - // Err(error) => Value::Error { error }, - // } - // }) - // .into_value_stream(), - // span: call.head, - // }), - // Value::Stream { stream, .. } => Ok(Value::Stream { - // stream: stream - // .enumerate() - // .map(move |(idx, x)| { - // let engine_state = context.engine_state.borrow(); - // let block = engine_state.get_block(block_id); + match eval_block(&state, block, PipelineData::new()) { + Ok(v) => v, + Err(error) => Value::Error { error }.into_pipeline_data(), + } + }) + .flatten() + .into_pipeline_data()), + PipelineData::Stream(stream) => Ok(stream + .enumerate() + .map(move |(idx, x)| { + let block = context.engine_state.get_block(block_id); - // let state = context.enter_scope(); - // if let Some(var) = block.signature.get_positional(0) { - // if let Some(var_id) = &var.var_id { - // if numbered { - // state.add_var( - // *var_id, - // Value::Record { - // cols: vec!["index".into(), "item".into()], - // vals: vec![ - // Value::Int { - // val: idx as i64, - // span, - // }, - // x, - // ], - // span, - // }, - // ); - // } else { - // state.add_var(*var_id, x); - // } - // } - // } + let state = context.enter_scope(); + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + if numbered { + state.add_var( + *var_id, + Value::Record { + cols: vec!["index".into(), "item".into()], + vals: vec![ + Value::Int { + val: idx as i64, + span, + }, + x, + ], + span, + }, + ); + } else { + state.add_var(*var_id, x); + } + } + } - // match eval_block(&state, block, Value::nothing()) { - // Ok(v) => v, - // Err(error) => Value::Error { error }, - // } - // }) - // .into_value_stream(), - // span: call.head, - // }), - // Value::Record { cols, vals, .. } => { - // let mut output_cols = vec![]; - // let mut output_vals = vec![]; + match eval_block(&state, block, PipelineData::new()) { + Ok(v) => v, + Err(error) => Value::Error { error }.into_pipeline_data(), + } + }) + .flatten() + .into_pipeline_data()), + PipelineData::Value(Value::Record { cols, vals, .. }) => { + let mut output_cols = vec![]; + let mut output_vals = vec![]; - // for (col, val) in cols.into_iter().zip(vals.into_iter()) { - // let engine_state = context.engine_state.borrow(); - // let block = engine_state.get_block(block_id); + for (col, val) in cols.into_iter().zip(vals.into_iter()) { + let block = context.engine_state.get_block(block_id); - // let state = context.enter_scope(); - // if let Some(var) = block.signature.get_positional(0) { - // if let Some(var_id) = &var.var_id { - // state.add_var( - // *var_id, - // Value::Record { - // cols: vec!["column".into(), "value".into()], - // vals: vec![ - // Value::String { - // val: col.clone(), - // span: call.head, - // }, - // val, - // ], - // span: call.head, - // }, - // ); - // } - // } + let state = context.enter_scope(); + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + state.add_var( + *var_id, + Value::Record { + cols: vec!["column".into(), "value".into()], + vals: vec![ + Value::String { + val: col.clone(), + span: call.head, + }, + val, + ], + span: call.head, + }, + ); + } + } - // match eval_block(&state, block, Value::nothing())? { - // Value::Record { - // mut cols, mut vals, .. - // } => { - // // TODO check that the lengths match when traversing record - // output_cols.append(&mut cols); - // output_vals.append(&mut vals); - // } - // x => { - // output_cols.push(col); - // output_vals.push(x); - // } - // } - // } + match eval_block(&state, block, PipelineData::new())? { + PipelineData::Value(Value::Record { + mut cols, mut vals, .. + }) => { + // TODO check that the lengths match when traversing record + output_cols.append(&mut cols); + output_vals.append(&mut vals); + } + x => { + output_cols.push(col); + output_vals.push(x.into_value()); + } + } + } - // Ok(Value::Record { - // cols: output_cols, - // vals: output_vals, - // span: call.head, - // }) - // } - // x => { - // let engine_state = context.engine_state.borrow(); - // let block = engine_state.get_block(block_id); + Ok(Value::Record { + cols: output_cols, + vals: output_vals, + span: call.head, + } + .into_pipeline_data()) + } + PipelineData::Value(x) => { + let block = context.engine_state.get_block(block_id); - // let state = context.enter_scope(); - // if let Some(var) = block.signature.get_positional(0) { - // if let Some(var_id) = &var.var_id { - // state.add_var(*var_id, x); - // } - // } + let state = context.enter_scope(); + if let Some(var) = block.signature.get_positional(0) { + if let Some(var_id) = &var.var_id { + state.add_var(*var_id, x); + } + } - // eval_block(&state, block, Value::nothing()) - // } - // } + eval_block(&state, block, PipelineData::new()) + } + } } } diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index 9cf3dd7963..fd4084e2bf 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -1,7 +1,7 @@ use nu_engine::CallExt; use nu_protocol::ast::{Call, CellPath}; use nu_protocol::engine::{Command, EvaluationContext}; -use nu_protocol::{PipelineData, Signature, SyntaxShape, Value}; +use nu_protocol::{IntoPipelineData, PipelineData, Signature, SyntaxShape, Value}; #[derive(Clone)] pub struct Get; @@ -31,6 +31,8 @@ impl Command for Get { ) -> Result { let cell_path: CellPath = call.req(context, 0)?; - input.follow_cell_path(&cell_path.members) + input + .follow_cell_path(&cell_path.members) + .map(|x| x.into_pipeline_data()) } } diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index 37ee0f81ff..598544aafd 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -72,7 +72,7 @@ impl Command for FromJson { call: &Call, input: PipelineData, ) -> Result { - let span = input.span()?; + let span = call.head; let mut string_input = input.collect_string(); string_input.push('\n'); diff --git a/crates/nu-command/src/viewers/griddle.rs b/crates/nu-command/src/viewers/griddle.rs index 42d66d7edb..462c476abd 100644 --- a/crates/nu-command/src/viewers/griddle.rs +++ b/crates/nu-command/src/viewers/griddle.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::{Call, PathMember}, engine::{Command, EvaluationContext}, - Signature, Span, SyntaxShape, Value, + IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value, }; use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions}; use terminal_size::{Height, Width}; @@ -50,14 +50,14 @@ prints out the list properly."# &self, context: &EvaluationContext, call: &Call, - input: Value, - ) -> Result { + input: PipelineData, + ) -> Result { let width_param: Option = call.get_flag(context, "width")?; let color_param: bool = call.has_flag("color"); let separator_param: Option = call.get_flag(context, "separator")?; match input { - Value::List { vals, .. } => { + PipelineData::Value(Value::List { vals, .. }) => { // dbg!("value::list"); let data = convert_to_list2(vals); if let Some(items) = data { @@ -69,10 +69,10 @@ prints out the list properly."# separator_param, )) } else { - Ok(Value::Nothing { span: call.head }) + Ok(PipelineData::new()) } } - Value::Stream { stream, .. } => { + PipelineData::Stream(stream) => { // dbg!("value::stream"); let data = convert_to_list2(stream); if let Some(items) = data { @@ -85,10 +85,10 @@ prints out the list properly."# )) } else { // dbg!(data); - Ok(Value::Nothing { span: call.head }) + Ok(PipelineData::new()) } } - Value::Record { cols, vals, .. } => { + PipelineData::Value(Value::Record { cols, vals, .. }) => { // dbg!("value::record"); let mut items = vec![]; @@ -119,7 +119,7 @@ fn create_grid_output2( width_param: Option, color_param: bool, separator_param: Option, -) -> Value { +) -> PipelineData { let ls_colors = LsColors::from_env().unwrap_or_default(); let cols = if let Some(col) = width_param { col.parse::().unwrap_or(80) @@ -167,6 +167,7 @@ fn create_grid_output2( span: call.head, } } + .into_pipeline_data() } fn convert_to_list2(iter: impl IntoIterator) -> Option> { diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index 3d5f94992f..131207f552 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -1,6 +1,6 @@ use nu_protocol::ast::{Call, PathMember}; use nu_protocol::engine::{Command, EvaluationContext}; -use nu_protocol::{ShellError, Signature, Span, Value}; +use nu_protocol::{IntoPipelineData, PipelineData, ShellError, Signature, Span, Value}; use nu_table::StyledString; use std::collections::HashMap; use terminal_size::{Height, Width}; @@ -26,8 +26,8 @@ impl Command for Table { &self, _context: &EvaluationContext, call: &Call, - input: Value, - ) -> Result { + input: PipelineData, + ) -> Result { let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() { w as usize } else { @@ -35,7 +35,7 @@ impl Command for Table { }; match input { - Value::List { vals, .. } => { + PipelineData::Value(Value::List { vals, .. }) => { let table = convert_to_table(vals)?; if let Some(table) = table { @@ -44,12 +44,13 @@ impl Command for Table { Ok(Value::String { val: result, span: call.head, - }) + } + .into_pipeline_data()) } else { - Ok(Value::Nothing { span: call.head }) + Ok(PipelineData::new()) } } - Value::Stream { stream, .. } => { + PipelineData::Stream(stream) => { let table = convert_to_table(stream)?; if let Some(table) = table { @@ -58,12 +59,13 @@ impl Command for Table { Ok(Value::String { val: result, span: call.head, - }) + } + .into_pipeline_data()) } else { - Ok(Value::Nothing { span: call.head }) + Ok(PipelineData::new()) } } - Value::Record { cols, vals, .. } => { + PipelineData::Value(Value::Record { cols, vals, .. }) => { let mut output = vec![]; for (c, v) in cols.into_iter().zip(vals.into_iter()) { @@ -90,9 +92,10 @@ impl Command for Table { Ok(Value::String { val: result, span: call.head, - }) + } + .into_pipeline_data()) } - Value::Error { error } => Err(error), + PipelineData::Value(Value::Error { error }) => Err(error), x => Ok(x), } } diff --git a/crates/nu-protocol/src/pipeline_data.rs b/crates/nu-protocol/src/pipeline_data.rs index 9b110f6419..d8c1836ee5 100644 --- a/crates/nu-protocol/src/pipeline_data.rs +++ b/crates/nu-protocol/src/pipeline_data.rs @@ -1,4 +1,4 @@ -use crate::{Span, Value, ValueStream}; +use crate::{ast::PathMember, ShellError, Span, Value, ValueStream}; pub enum PipelineData { Value(Value), @@ -19,6 +19,25 @@ impl PipelineData { }, } } + + pub fn collect_string(self) -> String { + match self { + PipelineData::Value(v) => v.collect_string(), + PipelineData::Stream(s) => s.collect_string(), + } + } + + pub fn follow_cell_path(self, cell_path: &[PathMember]) -> Result { + match self { + // FIXME: there are probably better ways of doing this + PipelineData::Stream(stream) => Value::List { + vals: stream.collect(), + span: Span::unknown(), + } + .follow_cell_path(cell_path), + PipelineData::Value(v) => v.follow_cell_path(cell_path), + } + } } impl Default for PipelineData {