Skip to content

Commit f08b889

Browse files
committed
Treat a list of empty strings as Nothing
1 parent 26b5e70 commit f08b889

1 file changed

Lines changed: 44 additions & 9 deletions

File tree

src/convert.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,34 @@ pub fn trim_string(s: &String) -> &str {
88
s.trim_matches(TRIM_CHARS)
99
}
1010

11+
fn is_nothing(value: &PrimitiveValue) -> bool {
12+
if let PrimitiveValue::Empty = value {
13+
return true;
14+
}
15+
16+
// Get strings and check if they're all empty/whitespace
17+
let strings = value.to_multi_str();
18+
19+
if strings.is_empty() {
20+
return true;
21+
}
22+
23+
// if all strings are empty/whitespace, return true; otherwise we assume there is a value
24+
strings
25+
.iter()
26+
.all(|s| trim_string(s).is_empty())
27+
}
28+
1129
pub struct Stringlike<'a>(pub &'a PrimitiveValue, pub Span);
1230
pub struct Integerlike<'a>(pub &'a PrimitiveValue, pub Span);
1331
pub struct Decimallike<'a>(pub &'a PrimitiveValue, pub Span);
1432

1533
impl From<Stringlike<'_>> for Value {
1634
fn from(v: Stringlike) -> Self {
35+
if is_nothing(v.0) {
36+
return Value::nothing(v.1);
37+
}
38+
1739
// TODO use rows/table like below?
1840
let val =
1941
v.0.to_multi_str()
@@ -26,10 +48,12 @@ impl From<Stringlike<'_>> for Value {
2648

2749
impl From<Integerlike<'_>> for Value {
2850
fn from(v: Integerlike) -> Self {
51+
if is_nothing(v.0) {
52+
return Value::nothing(v.1);
53+
}
54+
2955
// TODO is i64 enough?
30-
let i =
31-
v.0.to_multi_int::<i64>()
32-
.expect("Failed to parse Integerlike to i64");
56+
let i = unwrap_or_panic_with_primitive(v.0.to_multi_int::<i64>(), v.0, "Failed to parse Integerlike to i64");
3357

3458
match i.len() {
3559
0 => Value::nothing(v.1),
@@ -49,14 +73,11 @@ impl From<Integerlike<'_>> for Value {
4973

5074
impl From<Decimallike<'_>> for Value {
5175
fn from(v: Decimallike) -> Self {
52-
// empty shortcut (not handled by to_multi_float64())
53-
if let PrimitiveValue::Empty = v.0 {
76+
if is_nothing(v.0) {
5477
return Value::nothing(v.1);
55-
};
78+
}
5679

57-
let i =
58-
v.0.to_multi_float64()
59-
.expect("Failed to parse Decimallike to f64");
80+
let i = unwrap_or_panic_with_primitive(v.0.to_multi_float64(), v.0, "Failed to parse Decimallike to f64");
6081

6182
match i.len() {
6283
0 => Value::nothing(v.1),
@@ -73,3 +94,17 @@ impl From<Decimallike<'_>> for Value {
7394
}
7495
}
7596
}
97+
98+
/// Helper function that panics with the PrimitiveValue pretty printed on error
99+
fn unwrap_or_panic_with_primitive<T, E>(
100+
result: Result<T, E>,
101+
primitive_value: &PrimitiveValue,
102+
operation: &str,
103+
) -> T {
104+
match result {
105+
Ok(value) => value,
106+
Err(_) => {
107+
panic!("{}: PrimitiveValue = {:#?}", operation, primitive_value);
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)