Prevent duplicate keys for lazy make (#11808)

# Description
Fixes #11755: `lazy make` also allows duplicate record keys
This commit is contained in:
Ian Manske 2024-02-14 00:00:52 +00:00 committed by GitHub
parent 7a181960b7
commit d77eeeb5dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,3 +1,5 @@
use std::collections::hash_map::Entry;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use nu_engine::{eval_block, CallExt};
@ -5,7 +7,7 @@ use nu_protocol::ast::Call;
use nu_protocol::engine::{Closure, Command, EngineState, Stack};
use nu_protocol::{
Category, Example, IntoPipelineData, LazyRecord, PipelineData, ShellError, Signature, Span,
SyntaxShape, Type, Value,
Spanned, SyntaxShape, Type, Value,
};
#[derive(Clone)]
@ -58,18 +60,36 @@ impl Command for LazyMake {
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let span = call.head;
let columns: Vec<String> = call
let columns: Vec<Spanned<String>> = call
.get_flag(engine_state, stack, "columns")?
.expect("required flag");
let get_value: Closure = call
.get_flag(engine_state, stack, "get-value")?
.expect("required flag");
let mut unique = HashMap::with_capacity(columns.len());
for col in &columns {
match unique.entry(&col.item) {
Entry::Occupied(entry) => {
return Err(ShellError::ColumnDefinedTwice {
col_name: col.item.clone(),
second_use: col.span,
first_use: *entry.get(),
});
}
Entry::Vacant(entry) => {
entry.insert(col.span);
}
}
}
Ok(Value::lazy_record(
Box::new(NuLazyRecord {
engine_state: engine_state.clone(),
stack: Arc::new(Mutex::new(stack.clone())),
columns,
columns: columns.into_iter().map(|s| s.item).collect(),
get_value,
span,
}),