Skip to content

Commit ab42fe4

Browse files
authored
Merge pull request #6 from FluidInference/fix/money-measure-parsing
fix: currency trailing dot panic and measure parser premature exit
2 parents d63af65 + 90e6445 commit ab42fe4

2 files changed

Lines changed: 31 additions & 3 deletions

File tree

src/tts/measure.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,14 @@ pub fn parse(input: &str) -> Option<String> {
152152
if clean.contains('.') {
153153
let parts: Vec<&str> = clean.splitn(2, '.').collect();
154154
if parts.len() == 2 {
155-
let int_val: i64 = parts[0].parse().ok()?;
155+
let int_val: i64 = if parts[0].is_empty() {
156+
0
157+
} else {
158+
let Ok(v) = parts[0].parse::<i64>() else {
159+
continue;
160+
};
161+
v
162+
};
156163
let int_words = number_to_words(int_val);
157164
let frac_words = super::spell_digits(parts[1]);
158165
let unit_word = unit_info.plural; // decimals are usually plural
@@ -166,7 +173,9 @@ pub fn parse(input: &str) -> Option<String> {
166173
continue;
167174
}
168175

169-
let n: i64 = clean.parse().ok()?;
176+
let Ok(n) = clean.parse::<i64>() else {
177+
continue;
178+
};
170179
let num_words = if is_negative {
171180
format!("minus {}", number_to_words(n))
172181
} else {
@@ -232,6 +241,15 @@ mod tests {
232241
assert_eq!(parse("1 GB"), Some("one gigabyte".to_string()));
233242
}
234243

244+
#[test]
245+
fn test_decimal_with_empty_integer() {
246+
// ".5 kg" should not cause premature return — continue to next unit
247+
assert_eq!(
248+
parse(".5 kg"),
249+
Some("zero point five kilograms".to_string())
250+
);
251+
}
252+
235253
#[test]
236254
fn test_non_measure() {
237255
assert_eq!(parse("hello"), None);

src/tts/money.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,9 @@ fn parse_dollars_cents(amount: &str, currency: &Currency) -> Option<String> {
148148
let cents_str = parts[1];
149149

150150
// Pad or truncate cents to 2 digits
151-
let cents: i64 = if cents_str.len() == 1 {
151+
let cents: i64 = if cents_str.is_empty() {
152+
0
153+
} else if cents_str.len() == 1 {
152154
cents_str.parse::<i64>().ok()? * 10
153155
} else if cents_str.len() == 2 {
154156
cents_str.parse().ok()?
@@ -258,6 +260,14 @@ mod tests {
258260
assert_eq!(parse("¥500"), Some("five hundred yen".to_string()));
259261
}
260262

263+
#[test]
264+
fn test_trailing_dot() {
265+
// "$5." should not panic — empty cents treated as zero
266+
assert_eq!(parse("$5."), Some("five dollars".to_string()));
267+
assert_eq!(parse("$1."), Some("one dollar".to_string()));
268+
assert_eq!(parse("$0."), Some("zero dollars".to_string()));
269+
}
270+
261271
#[test]
262272
fn test_non_money() {
263273
assert_eq!(parse("hello"), None);

0 commit comments

Comments
 (0)