Fix out of bounds in header command when row size is different (#2437)

* Use header vec to loop over the row instead of the row itself to fix out of bounds

* Fixed formatting
This commit is contained in:
Dillen Meijboom 2020-08-28 20:32:08 +02:00 committed by GitHub
parent 02763b47f7
commit 11ea5e61fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,7 +5,7 @@ use futures::stream::StreamExt;
use indexmap::IndexMap; use indexmap::IndexMap;
use nu_errors::ShellError; use nu_errors::ShellError;
use nu_protocol::Dictionary; use nu_protocol::Dictionary;
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue, Value}; use nu_protocol::{Primitive, ReturnSuccess, Signature, UntaggedValue, Value};
pub struct Headers; pub struct Headers;
@ -32,11 +32,18 @@ impl WholeStreamCommand for Headers {
} }
fn examples(&self) -> Vec<Example> { fn examples(&self) -> Vec<Example> {
vec![Example { vec![
Example {
description: "Create headers for a raw string", description: "Create headers for a raw string",
example: r#"echo "a b c|1 2 3" | split row "|" | split column " " | headers"#, example: r#"echo "a b c|1 2 3" | split row "|" | split column " " | headers"#,
result: None, result: None,
}] },
Example {
description: "Don't panic on rows with different headers",
example: r#"echo "a b c|1 2 3|1 2 3 4" | split row "|" | split column " " | headers"#,
result: None,
},
]
} }
} }
@ -84,8 +91,13 @@ pub async fn headers(
match &r.value { match &r.value {
UntaggedValue::Row(d) => { UntaggedValue::Row(d) => {
let mut entries = IndexMap::new(); let mut entries = IndexMap::new();
for (i, (_, v)) in d.entries.iter().enumerate() { for (i, header) in headers.iter().enumerate() {
entries.insert(headers[i].clone(), v.clone()); let value = match d.entries.get_index(i) {
Some((_, value)) => value.clone(),
None => UntaggedValue::Primitive(Primitive::Nothing).into(),
};
entries.insert(header.clone(), value);
} }
Ok(ReturnSuccess::Value( Ok(ReturnSuccess::Value(
UntaggedValue::Row(Dictionary { entries }).into_value(r.tag.clone()), UntaggedValue::Row(Dictionary { entries }).into_value(r.tag.clone()),