From 0f937fe9a8719b443f7198a3011912a3260c4efb Mon Sep 17 00:00:00 2001 From: electria Date: Mon, 19 Oct 2026 00:18:05 -0700 Subject: [PATCH] fix(formatting): split on last match the implementation doesn't look very performant, since it calls rfind and then rsplit_once. using split_at to replace the second call is a little more difficult tho --- src/formatting.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/formatting.rs b/src/formatting.rs index 5d492ab..bea3a6c 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -3,7 +3,7 @@ use rug::Float; use crate::nodes::{self, Error}; pub fn pretty_eval(input: &str, max_digits: usize) -> Result { - let (prefix, deliminator, input) = input.rsplit_once_any(&["plus.minus ", "& ", "= "]); + let (prefix, deliminator, input) = input.rsplit_once_last(&["= ", "& ", "plus.minus "]); // no need to remove the character here, // as we ignore it in all other logic already @@ -32,22 +32,25 @@ pub fn pretty_eval(input: &str, max_digits: usize) -> Result { } trait StrExt { - fn rsplit_once_any<'a>( + fn rsplit_once_last<'a>( &'a self, delimiters: &[&'static str], ) -> (&'a str, &'static str, &'a str); } impl StrExt for str { - fn rsplit_once_any<'a>( + fn rsplit_once_last<'a>( &'a self, delimiters: &[&'static str], ) -> (&'a str, &'static str, &'a str) { - for delimiter in delimiters { - if let Some((prefix, suffix)) = self.rsplit_once(delimiter) { - return (prefix, delimiter, suffix); - } - } - return ("", "", self); + delimiters + .iter() + .filter_map(|delimiter| self.rfind(delimiter).map(|i| (delimiter, i))) + .max_by_key(|(_, i)| *i) + .map(|(delimiter, _)| { + let (prefix, suffix) = self.rsplit_once(delimiter).unwrap(); + (prefix, *delimiter, suffix) + }) + .unwrap_or(("", "", self)) } } @@ -124,6 +127,14 @@ mod tests { assert_eq!(pretty_eval("-11", MAX_DIGITS).unwrap(), "-11"); } + #[test] + fn complex_prefix() { + assert_eq!( + pretty_eval("plus.minus 5 & = 5", MAX_DIGITS).unwrap(), + "plus.minus 5 & = 5" + ); + } + #[test] fn basic_get_significant_digits() { let many_zeros = eval("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4");