mirror of
https://github.com/nushell/nushell
synced 2024-12-26 13:03:07 +00:00
Have from-ssv not fail for header-only inputs (#1334)
This commit is contained in:
parent
427bde83f7
commit
fa910b95b7
1 changed files with 37 additions and 54 deletions
|
@ -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(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue