Skip to content

Commit 07c6640

Browse files
authored
fix: array elements starting with number followed by text parsed as string (#57)
* fix: array elements starting with number followed by text now parsed as string When parsing inline array values, numbers followed by string tokens (e.g., `1.0 something`) were incorrectly truncated to just the number. The fix checks for trailing string tokens after Number/Integer tokens in parse_tabular_field_value() and treats the combined value as a string, matching the behavior of regular field value parsing. Fixes #56 * fix: use non-PI float in test to satisfy clippy approx_constant lint
1 parent 4fee255 commit 07c6640

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

src/decode/parser.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,13 +1125,32 @@ impl<'a> Parser<'a> {
11251125
Token::Integer(i) => {
11261126
let val = *i;
11271127
self.advance()?;
1128-
Ok(Number::from(val).into())
1128+
// If followed by string tokens, treat the whole value as a string
1129+
if let Token::String(..) = &self.current_token {
1130+
let mut accumulated = val.to_string();
1131+
while let Token::String(next, _) = &self.current_token {
1132+
accumulated.push(' ');
1133+
accumulated.push_str(next);
1134+
self.advance()?;
1135+
}
1136+
Ok(Value::String(accumulated))
1137+
} else {
1138+
Ok(Number::from(val).into())
1139+
}
11291140
}
11301141
Token::Number(n) => {
11311142
let val = *n;
11321143
self.advance()?;
1133-
// If the float is actually an integer, represent it as such
1134-
if val.is_finite() && val.fract() == 0.0 && val.abs() <= i64::MAX as f64 {
1144+
// If followed by string tokens, treat the whole value as a string
1145+
if let Token::String(..) = &self.current_token {
1146+
let mut accumulated = val.to_string();
1147+
while let Token::String(next, _) = &self.current_token {
1148+
accumulated.push(' ');
1149+
accumulated.push_str(next);
1150+
self.advance()?;
1151+
}
1152+
Ok(Value::String(accumulated))
1153+
} else if val.is_finite() && val.fract() == 0.0 && val.abs() <= i64::MAX as f64 {
11351154
Ok(Number::from(val as i64).into())
11361155
} else {
11371156
Ok(Number::from_f64(val)
@@ -1670,4 +1689,22 @@ hello: 0(f)"#;
16701689
})
16711690
);
16721691
}
1692+
1693+
#[test]
1694+
fn test_array_element_number_followed_by_string() {
1695+
// Issue #56: Array elements starting with a number should be parsed as string
1696+
// when followed by non-numeric text
1697+
let result = parse("version1[1]: 1.0 something").unwrap();
1698+
assert_eq!(result["version1"], json!(["1 something"]));
1699+
1700+
let result = parse("data[1]: 42 units").unwrap();
1701+
assert_eq!(result["data"], json!(["42 units"]));
1702+
1703+
// Pure numbers should still be parsed as numbers
1704+
let result = parse("nums[1]: 42").unwrap();
1705+
assert_eq!(result["nums"], json!([42]));
1706+
1707+
let result = parse("nums[1]: 2.75").unwrap();
1708+
assert_eq!(result["nums"], json!([2.75]));
1709+
}
16731710
}

0 commit comments

Comments
 (0)