Have from-ssv not fail for header-only inputs (#1334)

This commit is contained in:
Jason Gedge 2020-02-05 14:54:14 -05:00 committed by GitHub
parent 427bde83f7
commit fa910b95b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -197,15 +197,17 @@ fn string_to_table(
headerless: bool, headerless: bool,
aligned_columns: bool, aligned_columns: bool,
split_at: usize, split_at: usize,
) -> Option<Vec<Vec<(String, String)>>> { ) -> Vec<Vec<(String, String)>> {
let mut lines = s.lines().filter(|l| !l.trim().is_empty()); let mut lines = s.lines().filter(|l| !l.trim().is_empty());
let separator = " ".repeat(std::cmp::max(split_at, 1)); let separator = " ".repeat(std::cmp::max(split_at, 1));
let (ls, header_options) = if headerless { let (ls, header_options) = if headerless {
(lines, HeaderOptions::WithoutHeaders) (lines, HeaderOptions::WithoutHeaders)
} else { } else {
let headers = lines.next()?; match lines.next() {
(lines, HeaderOptions::WithHeaders(headers)) Some(header) => (lines, HeaderOptions::WithHeaders(header)),
None => return vec![],
}
}; };
let f = if aligned_columns { let f = if aligned_columns {
@ -214,11 +216,7 @@ fn string_to_table(
parse_separated_columns parse_separated_columns
}; };
let parsed = f(ls, header_options, &separator); f(ls, header_options, &separator)
match parsed.len() {
0 => None,
_ => Some(parsed),
}
} }
fn from_ssv_string_to_value( fn from_ssv_string_to_value(
@ -229,7 +227,7 @@ fn from_ssv_string_to_value(
tag: impl Into<Tag>, tag: impl Into<Tag>,
) -> Option<Value> { ) -> Option<Value> {
let tag = tag.into(); let tag = tag.into();
let rows = string_to_table(s, headerless, aligned_columns, split_at)? let rows = string_to_table(s, headerless, aligned_columns, split_at)
.iter() .iter()
.map(|row| { .map(|row| {
let mut tagged_dict = TaggedDictBuilder::new(&tag); let mut tagged_dict = TaggedDictBuilder::new(&tag);
@ -323,10 +321,10 @@ mod tests {
let result = string_to_table(input, false, true, 1); let result = string_to_table(input, false, true, 1);
assert_eq!( assert_eq!(
result, result,
Some(vec![ vec![
vec![owned("a", "1"), owned("b", "2")], vec![owned("a", "1"), owned("b", "2")],
vec![owned("a", "3"), owned("b", "4")] vec![owned("a", "3"), owned("b", "4")]
]) ]
); );
} }
@ -338,10 +336,7 @@ mod tests {
2 2
"#; "#;
let result = string_to_table(input, false, true, 1); let result = string_to_table(input, false, true, 1);
assert_eq!( assert_eq!(result, vec![vec![owned("a", "1")], vec![owned("a", "2")]]);
result,
Some(vec![vec![owned("a", "1")], vec![owned("a", "2")]])
);
} }
#[test] #[test]
@ -354,21 +349,14 @@ mod tests {
let result = string_to_table(input, true, true, 1); let result = string_to_table(input, true, true, 1);
assert_eq!( assert_eq!(
result, result,
Some(vec![ vec![
vec![owned("Column1", "a"), owned("Column2", "b")], vec![owned("Column1", "a"), owned("Column2", "b")],
vec![owned("Column1", "1"), owned("Column2", "2")], vec![owned("Column1", "1"), owned("Column2", "2")],
vec![owned("Column1", "3"), owned("Column2", "4")] vec![owned("Column1", "3"), owned("Column2", "4")]
]) ]
); );
} }
#[test]
fn it_returns_none_given_an_empty_string() {
let input = "";
let result = string_to_table(input, true, true, 1);
assert!(result.is_none());
}
#[test] #[test]
fn it_allows_a_predefined_number_of_spaces() { fn it_allows_a_predefined_number_of_spaces() {
let input = r#" let input = r#"
@ -380,18 +368,18 @@ mod tests {
let result = string_to_table(input, false, true, 3); let result = string_to_table(input, false, true, 3);
assert_eq!( assert_eq!(
result, result,
Some(vec![ vec![
vec![ vec![
owned("column a", "entry 1"), owned("column a", "entry 1"),
owned("column b", "entry number 2") owned("column b", "entry number 2")
], ],
vec![owned("column a", "3"), owned("column b", "four")] vec![owned("column a", "3"), owned("column b", "four")]
]) ]
); );
} }
#[test] #[test]
fn it_trims_remaining_separator_space() -> Result<(), ShellError> { fn it_trims_remaining_separator_space() {
let input = r#" let input = r#"
colA colB colC colA colB colC
val1 val2 val3 val1 val2 val3
@ -399,17 +387,14 @@ mod tests {
let trimmed = |s: &str| s.trim() == s; let trimmed = |s: &str| s.trim() == s;
let result = string_to_table(input, false, true, 2) let result = string_to_table(input, false, true, 2);
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?;
assert!(result assert!(result
.iter() .iter()
.all(|row| row.iter().all(|(a, b)| trimmed(a) && trimmed(b)))); .all(|row| row.iter().all(|(a, b)| trimmed(a) && trimmed(b))));
Ok(())
} }
#[test] #[test]
fn it_keeps_empty_columns() -> Result<(), ShellError> { fn it_keeps_empty_columns() {
let input = r#" let input = r#"
colA col B col C colA col B col C
val2 val3 val2 val3
@ -417,8 +402,7 @@ mod tests {
val7 val8 val7 val8
"#; "#;
let result = string_to_table(input, false, true, 2) let result = string_to_table(input, false, true, 2);
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?;
assert_eq!( assert_eq!(
result, result,
vec![ vec![
@ -439,38 +423,43 @@ mod tests {
], ],
] ]
); );
Ok(())
} }
#[test] #[test]
fn it_uses_the_full_final_column() -> Result<(), ShellError> { fn it_can_produce_an_empty_stream_for_header_only_input() {
let input = "colA col B";
let result = string_to_table(input, false, true, 2);
let expected: Vec<Vec<(String, String)>> = vec![];
assert_eq!(expected, result);
}
#[test]
fn it_uses_the_full_final_column() {
let input = r#" let input = r#"
colA col B colA col B
val1 val2 trailing value that should be included val1 val2 trailing value that should be included
"#; "#;
let result = string_to_table(input, false, true, 2) let result = string_to_table(input, false, true, 2);
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?;
assert_eq!( assert_eq!(
result, result,
vec![vec![ vec![vec![
owned("colA", "val1"), owned("colA", "val1"),
owned("col B", "val2 trailing value that should be included"), owned("col B", "val2 trailing value that should be included"),
],] ]]
); );
Ok(())
} }
#[test] #[test]
fn it_handles_empty_values_when_headerless_and_aligned_columns() -> Result<(), ShellError> { fn it_handles_empty_values_when_headerless_and_aligned_columns() {
let input = r#" let input = r#"
a multi-word value b d a multi-word value b d
1 3-3 4 1 3-3 4
last last
"#; "#;
let result = string_to_table(input, true, true, 2) let result = string_to_table(input, true, true, 2);
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?;
assert_eq!( assert_eq!(
result, result,
vec![ vec![
@ -497,27 +486,21 @@ mod tests {
], ],
] ]
); );
Ok(())
} }
#[test] #[test]
fn input_is_parsed_correctly_if_either_option_works() -> Result<(), ShellError> { fn input_is_parsed_correctly_if_either_option_works() {
let input = r#" let input = r#"
docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP docker-registry docker-registry=default docker-registry=default 172.30.78.158 5000/TCP
kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP kubernetes component=apiserver,provider=kubernetes <none> 172.30.0.2 443/TCP
kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP kubernetes-ro component=apiserver,provider=kubernetes <none> 172.30.0.1 80/TCP
"#; "#;
let aligned_columns_headerless = string_to_table(input, true, true, 2) let aligned_columns_headerless = string_to_table(input, true, true, 2);
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?; let separator_headerless = string_to_table(input, true, false, 2);
let separator_headerless = string_to_table(input, true, false, 2) let aligned_columns_with_headers = string_to_table(input, false, true, 2);
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?; let separator_with_headers = string_to_table(input, false, false, 2);
let aligned_columns_with_headers = string_to_table(input, false, true, 2)
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?;
let separator_with_headers = string_to_table(input, false, false, 2)
.ok_or_else(|| ShellError::unexpected("table couldn't be parsed"))?;
assert_eq!(aligned_columns_headerless, separator_headerless); assert_eq!(aligned_columns_headerless, separator_headerless);
assert_eq!(aligned_columns_with_headers, separator_with_headers); assert_eq!(aligned_columns_with_headers, separator_with_headers);
Ok(())
} }
} }