Add an experimental record iteration

This commit is contained in:
JT 2021-09-08 10:00:20 +12:00
parent ab3820890b
commit 6dd9f05ea1
3 changed files with 59 additions and 4 deletions

View File

@ -38,7 +38,7 @@ impl Command for Each {
let block = engine_state.get_block(block_id);
let state = context.enter_scope();
if let Some(var) = block.signature.required_positional.first() {
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
state.add_var(*var_id, x);
}
@ -60,7 +60,7 @@ impl Command for Each {
let block = engine_state.get_block(block_id);
let state = context.enter_scope();
if let Some(var) = block.signature.required_positional.first() {
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
state.add_var(*var_id, x);
}
@ -81,7 +81,7 @@ impl Command for Each {
let block = engine_state.get_block(block_id);
let state = context.enter_scope();
if let Some(var) = block.signature.required_positional.first() {
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
state.add_var(*var_id, x);
}
@ -95,13 +95,62 @@ impl Command for Each {
.into_value_stream(),
span: call.head,
}),
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);
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
output_cols.append(&mut cols);
output_vals.append(&mut vals);
}
x => {
output_cols.push(col);
output_vals.push(x);
}
}
}
Ok(Value::Record {
cols: output_cols,
vals: output_vals,
span: call.head,
})
}
x => {
//TODO: we need to watch to make sure this is okay
let engine_state = context.engine_state.borrow();
let block = engine_state.get_block(block_id);
let state = context.enter_scope();
if let Some(var) = block.signature.required_positional.first() {
if let Some(var) = block.signature.get_positional(0) {
if let Some(var_id) = &var.var_id {
state.add_var(*var_id, x);
}

View File

@ -1876,6 +1876,7 @@ pub fn parse_block_expression(
error = error.or(err);
working_set.enter_scope();
// Check to see if we have parameters
let (signature, amt_to_skip): (Option<Box<Signature>>, usize) = match output.first() {
Some(Token {

View File

@ -287,3 +287,8 @@ fn row_iteration() -> TestResult {
"[800, 1600]",
)
}
#[test]
fn record_iteration() -> TestResult {
run_test("([[name, level]; [aa, 100], [bb, 200]] | each { $it | each { |x| if $x.column == \"level\" { $x.value + 100 } else { $x.value } } }).level", "[200, 300]")
}