Remove some unnecessary static Vecs (#11947)

Avoid unnecessary allocations or larger iterator structs

- Turn static `Vec`s into arrays when possible
- Use `std::iter::once`/`empty` where applicable
- Use `bool::then_some` in `detect column` `.chain`
- Drop in the bucket: de-vec-ing tests
This commit is contained in:
Stefan Holderbach 2024-02-24 20:58:01 +01:00 committed by GitHub
parent 098527b263
commit 7884de1941
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 115 additions and 113 deletions

View File

@ -253,7 +253,7 @@ mod command_completions_tests {
#[test] #[test]
fn test_find_non_whitespace_index() { fn test_find_non_whitespace_index() {
let commands = vec![ let commands = [
(" hello", 4), (" hello", 4),
("sudo ", 0), ("sudo ", 0),
(" sudo ", 2), (" sudo ", 2),
@ -273,7 +273,7 @@ mod command_completions_tests {
#[test] #[test]
fn test_is_last_command_passthrough() { fn test_is_last_command_passthrough() {
let commands = vec![ let commands = [
(" hello", false), (" hello", false),
(" sudo ", true), (" sudo ", true),
("sudo ", true), ("sudo ", true),

View File

@ -564,7 +564,7 @@ mod completer_tests {
); );
let mut completer = NuCompleter::new(engine_state.into(), Stack::new()); let mut completer = NuCompleter::new(engine_state.into(), Stack::new());
let dataset = vec![ let dataset = [
("sudo", false, "", Vec::new()), ("sudo", false, "", Vec::new()),
("sudo l", true, "l", vec!["ls", "let", "lines", "loop"]), ("sudo l", true, "l", vec!["ls", "let", "lines", "loop"]),
(" sudo", false, "", Vec::new()), (" sudo", false, "", Vec::new()),

View File

@ -84,7 +84,7 @@ pub(crate) fn add_menus(
} }
// Checking if the default menus have been added from the config file // Checking if the default menus have been added from the config file
let default_menus = vec![ let default_menus = [
("completion_menu", DEFAULT_COMPLETION_MENU), ("completion_menu", DEFAULT_COMPLETION_MENU),
("history_menu", DEFAULT_HISTORY_MENU), ("history_menu", DEFAULT_HISTORY_MENU),
("help_menu", DEFAULT_HELP_MENU), ("help_menu", DEFAULT_HELP_MENU),

View File

@ -154,9 +154,9 @@ impl Command for Do {
let ctrlc = stdout_stream.ctrlc.clone(); let ctrlc = stdout_stream.ctrlc.clone();
let span = stdout_stream.span; let span = stdout_stream.span;
RawStream::new( RawStream::new(
Box::new( Box::new(std::iter::once(
vec![stdout_stream.into_bytes().map(|s| s.item)].into_iter(), stdout_stream.into_bytes().map(|s| s.item),
), )),
ctrlc, ctrlc,
span, span,
None, None,
@ -213,7 +213,7 @@ impl Command for Do {
Ok(PipelineData::ExternalStream { Ok(PipelineData::ExternalStream {
stdout, stdout,
stderr: Some(RawStream::new( stderr: Some(RawStream::new(
Box::new(vec![Ok(stderr_msg.into_bytes())].into_iter()), Box::new(std::iter::once(Ok(stderr_msg.into_bytes()))),
stderr_ctrlc, stderr_ctrlc,
span, span,
None, None,

View File

@ -46,7 +46,7 @@ pub(crate) fn generate_strftime_list(head: Span, show_parse_only_formats: bool)
description: &'a str, description: &'a str,
} }
let specifications = vec![ let specifications = [
FormatSpecification { FormatSpecification {
spec: "%Y", spec: "%Y",
description: "The full proleptic Gregorian year, zero-padded to 4 digits.", description: "The full proleptic Gregorian year, zero-padded to 4 digits.",

View File

@ -85,7 +85,7 @@ If multiple cell paths are given, this will produce a list of values."#
} else { } else {
let mut output = vec![]; let mut output = vec![];
let paths = vec![cell_path].into_iter().chain(rest); let paths = std::iter::once(cell_path).chain(rest);
let input = input.into_value(span); let input = input.into_value(span);

View File

@ -128,118 +128,120 @@ fn detect_columns(
} }
} }
Ok((if noheader { Ok(noheader
vec![orig_headers].into_iter().chain(input) .then_some(orig_headers)
} else { .into_iter()
vec![].into_iter().chain(input) .chain(input)
}) .map(move |x| {
.map(move |x| { let row = find_columns(&x);
let row = find_columns(&x);
let mut record = Record::new(); let mut record = Record::new();
if headers.len() == row.len() { if headers.len() == row.len() {
for (header, val) in headers.iter().zip(row.iter()) { for (header, val) in headers.iter().zip(row.iter()) {
record.push(&header.item, Value::string(&val.item, name_span)); record.push(&header.item, Value::string(&val.item, name_span));
} }
} else { } else {
let mut pre_output = vec![]; let mut pre_output = vec![];
// column counts don't line up, so see if we can figure out why
for cell in row {
for header in &headers {
if cell.span.start <= header.span.end
&& cell.span.end > header.span.start
{
pre_output.push((
header.item.to_string(),
Value::string(&cell.item, name_span),
));
}
}
}
// column counts don't line up, so see if we can figure out why
for cell in row {
for header in &headers { for header in &headers {
if cell.span.start <= header.span.end && cell.span.end > header.span.start { let mut found = false;
pre_output.push(( for pre_o in &pre_output {
header.item.to_string(), if pre_o.0 == header.item {
Value::string(&cell.item, name_span), found = true;
)); break;
}
}
if !found {
pre_output.push((header.item.to_string(), Value::nothing(name_span)));
}
}
for header in &headers {
for pre_o in &pre_output {
if pre_o.0 == header.item {
record.push(&header.item, pre_o.1.clone());
}
} }
} }
} }
for header in &headers { let (start_index, end_index) = if let Some(range) = &range {
let mut found = false; match nu_cmd_base::util::process_range(range) {
for pre_o in &pre_output { Ok((l_idx, r_idx)) => {
if pre_o.0 == header.item { let l_idx = if l_idx < 0 {
found = true; record.len() as isize + l_idx
break; } else {
l_idx
};
let r_idx = if r_idx < 0 {
record.len() as isize + r_idx
} else {
r_idx
};
if !(l_idx <= r_idx && (r_idx >= 0 || l_idx < (record.len() as isize)))
{
return Value::record(record, name_span);
}
(
l_idx.max(0) as usize,
(r_idx as usize + 1).min(record.len()),
)
}
Err(processing_error) => {
let err = processing_error("could not find range index", name_span);
return Value::error(err, name_span);
} }
} }
} else {
return Value::record(record, name_span);
};
if !found { let (mut cols, mut vals): (Vec<_>, Vec<_>) = record.into_iter().unzip();
pre_output.push((header.item.to_string(), Value::nothing(name_span)));
} // Merge Columns
((start_index + 1)..(cols.len() - end_index + start_index + 1)).for_each(|idx| {
cols.swap(idx, end_index - start_index - 1 + idx);
});
cols.truncate(cols.len() - end_index + start_index + 1);
// Merge Values
let combined = vals
.iter()
.take(end_index)
.skip(start_index)
.map(|v| v.coerce_str().unwrap_or_default())
.join(" ");
let binding = Value::string(combined, Span::unknown());
let last_seg = vals.split_off(end_index);
vals.truncate(start_index);
vals.push(binding);
vals.extend(last_seg);
match Record::from_raw_cols_vals(cols, vals, Span::unknown(), name_span) {
Ok(record) => Value::record(record, name_span),
Err(err) => Value::error(err, name_span),
} }
})
for header in &headers { .into_pipeline_data(ctrlc))
for pre_o in &pre_output {
if pre_o.0 == header.item {
record.push(&header.item, pre_o.1.clone());
}
}
}
}
let (start_index, end_index) = if let Some(range) = &range {
match nu_cmd_base::util::process_range(range) {
Ok((l_idx, r_idx)) => {
let l_idx = if l_idx < 0 {
record.len() as isize + l_idx
} else {
l_idx
};
let r_idx = if r_idx < 0 {
record.len() as isize + r_idx
} else {
r_idx
};
if !(l_idx <= r_idx && (r_idx >= 0 || l_idx < (record.len() as isize))) {
return Value::record(record, name_span);
}
(
l_idx.max(0) as usize,
(r_idx as usize + 1).min(record.len()),
)
}
Err(processing_error) => {
let err = processing_error("could not find range index", name_span);
return Value::error(err, name_span);
}
}
} else {
return Value::record(record, name_span);
};
let (mut cols, mut vals): (Vec<_>, Vec<_>) = record.into_iter().unzip();
// Merge Columns
((start_index + 1)..(cols.len() - end_index + start_index + 1)).for_each(|idx| {
cols.swap(idx, end_index - start_index - 1 + idx);
});
cols.truncate(cols.len() - end_index + start_index + 1);
// Merge Values
let combined = vals
.iter()
.take(end_index)
.skip(start_index)
.map(|v| v.coerce_str().unwrap_or_default())
.join(" ");
let binding = Value::string(combined, Span::unknown());
let last_seg = vals.split_off(end_index);
vals.truncate(start_index);
vals.push(binding);
vals.extend(last_seg);
match Record::from_raw_cols_vals(cols, vals, Span::unknown(), name_span) {
Ok(record) => Value::record(record, name_span),
Err(err) => Value::error(err, name_span),
}
})
.into_pipeline_data(ctrlc))
} else { } else {
Ok(PipelineData::empty()) Ok(PipelineData::empty())
} }

View File

@ -550,7 +550,7 @@ fn eval_element_with_input(
// so nushell knows this result is not the last part of a command. // so nushell knows this result is not the last part of a command.
( (
Some(RawStream::new( Some(RawStream::new(
Box::new(vec![].into_iter()), Box::new(std::iter::empty()),
None, None,
*span, *span,
Some(0), Some(0),

View File

@ -605,7 +605,7 @@ impl PipelineData {
.map(|bytes| bytes.item) .map(|bytes| bytes.item)
.unwrap_or_default(); .unwrap_or_default();
RawStream::new( RawStream::new(
Box::new(vec![Ok(stderr_bytes)].into_iter()), Box::new(std::iter::once(Ok(stderr_bytes))),
stderr_ctrlc, stderr_ctrlc,
stderr_span, stderr_span,
None, None,

View File

@ -82,7 +82,7 @@ impl NuProcess {
command.env_clear(); command.env_clear();
let paths = vec![test_bins_path()]; let paths = [test_bins_path()];
let paths_joined = match std::env::join_paths(paths) { let paths_joined = match std::env::join_paths(paths) {
Ok(all) => all, Ok(all) => all,