Use Record APIs in nu-protocol/nu-engine (#10917)

# Description
Consequences of #10841

This does not yet make the assumption that columns are always
duplicated. Follow the existing logic here

- Use saner record API in `nu-engine/src/eval.rs`
- Use checked record construction in `nu-engine/src/scope.rs`
- Use `values` iterator in `nu-engine/src/scope.rs`
- Use `columns` iterator in `nu_engine::get_columns()`
- Start using record API in `value/mod.rs`
- Use `.insert` in `eval_const.rs` Record code
- Record API for `eval_const.rs` table code

# User-Facing Changes
None

# Tests + Formatting
None
This commit is contained in:
Stefan Holderbach 2023-11-01 23:19:58 +01:00 committed by GitHub
parent 0569a9c92e
commit a46048f362
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 21 additions and 46 deletions

View File

@ -8,7 +8,7 @@ pub fn get_columns(input: &[Value]) -> Vec<String> {
return vec![]; return vec![];
}; };
for col in &val.cols { for col in val.columns() {
if !columns.contains(col) { if !columns.contains(col) {
columns.push(col.to_string()); columns.push(col.to_string());
} }

View File

@ -552,7 +552,7 @@ pub fn eval_expression(
for (col, val) in fields { for (col, val) in fields {
// avoid duplicate cols. // avoid duplicate cols.
let col_name = eval_expression(engine_state, stack, col)?.as_string()?; let col_name = eval_expression(engine_state, stack, col)?.as_string()?;
let pos = record.cols.iter().position(|c| c == &col_name); let pos = record.index_of(&col_name);
match pos { match pos {
Some(index) => { Some(index) => {
return Err(ShellError::ColumnDefinedTwice { return Err(ShellError::ColumnDefinedTwice {
@ -592,10 +592,7 @@ pub fn eval_expression(
row.push(eval_expression(engine_state, stack, expr)?); row.push(eval_expression(engine_state, stack, expr)?);
} }
output_rows.push(Value::record( output_rows.push(Value::record(
Record { Record::from_raw_cols_vals(output_headers.clone(), row),
cols: output_headers.clone(),
vals: row,
},
expr.span, expr.span,
)); ));
} }

View File

@ -198,9 +198,9 @@ impl<'e, 's> ScopeData<'e, 's> {
// input // input
sig_records.push(Value::record( sig_records.push(Value::record(
Record { Record::from_raw_cols_vals(
cols: sig_cols.clone(), sig_cols.clone(),
vals: vec![ vec![
Value::nothing(span), Value::nothing(span),
Value::string("input", span), Value::string("input", span),
Value::string(input_type.to_shape().to_string(), span), Value::string(input_type.to_shape().to_string(), span),
@ -210,7 +210,7 @@ impl<'e, 's> ScopeData<'e, 's> {
Value::nothing(span), Value::nothing(span),
Value::nothing(span), Value::nothing(span),
], ],
}, ),
span, span,
)); ));
@ -231,10 +231,7 @@ impl<'e, 's> ScopeData<'e, 's> {
]; ];
sig_records.push(Value::record( sig_records.push(Value::record(
Record { Record::from_raw_cols_vals(sig_cols.clone(), sig_vals),
cols: sig_cols.clone(),
vals: sig_vals,
},
span, span,
)); ));
} }
@ -260,10 +257,7 @@ impl<'e, 's> ScopeData<'e, 's> {
]; ];
sig_records.push(Value::record( sig_records.push(Value::record(
Record { Record::from_raw_cols_vals(sig_cols.clone(), sig_vals),
cols: sig_cols.clone(),
vals: sig_vals,
},
span, span,
)); ));
} }
@ -285,10 +279,7 @@ impl<'e, 's> ScopeData<'e, 's> {
]; ];
sig_records.push(Value::record( sig_records.push(Value::record(
Record { Record::from_raw_cols_vals(sig_cols.clone(), sig_vals),
cols: sig_cols.clone(),
vals: sig_vals,
},
span, span,
)); ));
} }
@ -335,19 +326,16 @@ impl<'e, 's> ScopeData<'e, 's> {
]; ];
sig_records.push(Value::record( sig_records.push(Value::record(
Record { Record::from_raw_cols_vals(sig_cols.clone(), sig_vals),
cols: sig_cols.clone(),
vals: sig_vals,
},
span, span,
)); ));
} }
// output // output
sig_records.push(Value::record( sig_records.push(Value::record(
Record { Record::from_raw_cols_vals(
cols: sig_cols, sig_cols,
vals: vec![ vec![
Value::nothing(span), Value::nothing(span),
Value::string("output", span), Value::string("output", span),
Value::string(output_type.to_shape().to_string(), span), Value::string(output_type.to_shape().to_string(), span),
@ -357,7 +345,7 @@ impl<'e, 's> ScopeData<'e, 's> {
Value::nothing(span), Value::nothing(span),
Value::nothing(span), Value::nothing(span),
], ],
}, ),
span, span,
)); ));
@ -587,7 +575,7 @@ fn sort_rows(decls: &mut [Value]) {
(Value::Record { val: rec_a, .. }, Value::Record { val: rec_b, .. }) => { (Value::Record { val: rec_a, .. }, Value::Record { val: rec_b, .. }) => {
// Comparing the first value from the record // Comparing the first value from the record
// It is expected that the first value is the name of the entry (command, module, alias, etc.) // It is expected that the first value is the name of the entry (command, module, alias, etc.)
match (rec_a.vals.get(0), rec_b.vals.get(0)) { match (rec_a.values().next(), rec_b.values().next()) {
(Some(val_a), Some(val_b)) => match (val_a, val_b) { (Some(val_a), Some(val_b)) => match (val_a, val_b) {
(Value::String { val: str_a, .. }, Value::String { val: str_b, .. }) => { (Value::String { val: str_a, .. }, Value::String { val: str_b, .. }) => {
str_a.cmp(str_b) str_a.cmp(str_b)

View File

@ -287,15 +287,7 @@ pub fn eval_constant(
for (col, val) in fields { for (col, val) in fields {
// avoid duplicate cols. // avoid duplicate cols.
let col_name = value_as_string(eval_constant(working_set, col)?, expr.span)?; let col_name = value_as_string(eval_constant(working_set, col)?, expr.span)?;
let pos = record.cols.iter().position(|c| c == &col_name); record.insert(col_name, eval_constant(working_set, val)?);
match pos {
Some(index) => {
record.vals[index] = eval_constant(working_set, val)?;
}
None => {
record.push(col_name, eval_constant(working_set, val)?);
}
}
} }
Ok(Value::record(record, expr.span)) Ok(Value::record(record, expr.span))
@ -323,11 +315,9 @@ pub fn eval_constant(
for expr in val { for expr in val {
row.push(eval_constant(working_set, expr)?); row.push(eval_constant(working_set, expr)?);
} }
// length equality already ensured in parser
output_rows.push(Value::record( output_rows.push(Value::record(
Record { Record::from_raw_cols_vals(output_headers.clone(), row),
cols: output_headers.clone(),
vals: row,
},
expr.span, expr.span,
)); ));
} }

View File

@ -3113,7 +3113,7 @@ impl Value {
} }
(lhs, Value::List { vals: rhs, .. }) => Ok(Value::bool(rhs.contains(lhs), span)), (lhs, Value::List { vals: rhs, .. }) => Ok(Value::bool(rhs.contains(lhs), span)),
(Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => { (Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => {
Ok(Value::bool(rhs.cols.contains(lhs), span)) Ok(Value::bool(rhs.contains(lhs), span))
} }
(Value::String { .. } | Value::Int { .. }, Value::CellPath { val: rhs, .. }) => { (Value::String { .. } | Value::Int { .. }, Value::CellPath { val: rhs, .. }) => {
let val = rhs.members.iter().any(|member| match (self, member) { let val = rhs.members.iter().any(|member| match (self, member) {
@ -3161,7 +3161,7 @@ impl Value {
} }
(lhs, Value::List { vals: rhs, .. }) => Ok(Value::bool(!rhs.contains(lhs), span)), (lhs, Value::List { vals: rhs, .. }) => Ok(Value::bool(!rhs.contains(lhs), span)),
(Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => { (Value::String { val: lhs, .. }, Value::Record { val: rhs, .. }) => {
Ok(Value::bool(!rhs.cols.contains(lhs), span)) Ok(Value::bool(!rhs.contains(lhs), span))
} }
(Value::String { .. } | Value::Int { .. }, Value::CellPath { val: rhs, .. }) => { (Value::String { .. } | Value::Int { .. }, Value::CellPath { val: rhs, .. }) => {
let val = rhs.members.iter().any(|member| match (self, member) { let val = rhs.members.iter().any(|member| match (self, member) {