mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Accept a negative operand after an operator in field arithmetic
Found while testing crates/doc/src/lib.rs:272 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Haiku 5.5
parent
8b22b07e09
commit
a59621fa78
@@ -273,7 +273,10 @@ fn parse_measure(s: &str, default: Unit) -> Option<f64> {
|
||||
for op in ['+', '-', '*', '/'] {
|
||||
// Past the first character, so a leading sign isn't an operator.
|
||||
let skip = s.chars().next().map_or(0, char::len_utf8);
|
||||
if let Some(i) = s[skip..].rfind(op).map(|i| i + skip) {
|
||||
// A `+` or `-` right after another operator is the sign of its operand (`10*-2`, `5--3`).
|
||||
let is_sign = |i: usize| matches!(op, '+' | '-') && s.get(..i).and_then(|l| l.trim_end().chars().last()).is_some_and(|c| "+-*/".contains(c));
|
||||
let found = s.char_indices().rev().find(|&(i, c)| i >= skip && c == op && !is_sign(i));
|
||||
if let Some(i) = found.map(|(i, _)| i) {
|
||||
let (l, r) = (&s[..i], &s[i + 1..]);
|
||||
if l.trim().is_empty() {
|
||||
continue;
|
||||
|
||||
@@ -66,3 +66,14 @@ fn readouts_show_two_decimals() {
|
||||
assert_eq!((Unit::Inches.number(595.2756), Unit::Points.number(595.2756)), ("8.2677".into(), "595.276".into()));
|
||||
assert_eq!(Unit::Points.number(-0.00001), "0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_negative_operand_after_an_operator_is_a_sign() {
|
||||
assert_eq!(Unit::Points.parse("10*-2"), Some(-20.0));
|
||||
assert_eq!(Unit::Points.parse("-10/-2"), Some(5.0));
|
||||
assert_eq!(Unit::Points.parse("5--3"), Some(8.0));
|
||||
assert_eq!(Unit::Points.parse("5 - -3"), Some(8.0));
|
||||
assert_eq!(Unit::Points.parse("5+-3"), Some(2.0));
|
||||
assert_eq!(Unit::Points.parse("10-2"), Some(8.0));
|
||||
assert_eq!(super::parse_number("90*-1"), Some(-90.0));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user