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
This commit is contained in:
electria 2026-10-19 00:18:05 -07:00
commit 0f937fe9a8
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs

View file

@ -3,7 +3,7 @@ use rug::Float;
use crate::nodes::{self, Error}; use crate::nodes::{self, Error};
pub fn pretty_eval(input: &str, max_digits: usize) -> Result<String, Error> { pub fn pretty_eval(input: &str, max_digits: usize) -> Result<String, Error> {
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, // no need to remove the character here,
// as we ignore it in all other logic already // as we ignore it in all other logic already
@ -32,22 +32,25 @@ pub fn pretty_eval(input: &str, max_digits: usize) -> Result<String, Error> {
} }
trait StrExt { trait StrExt {
fn rsplit_once_any<'a>( fn rsplit_once_last<'a>(
&'a self, &'a self,
delimiters: &[&'static str], delimiters: &[&'static str],
) -> (&'a str, &'static str, &'a str); ) -> (&'a str, &'static str, &'a str);
} }
impl StrExt for str { impl StrExt for str {
fn rsplit_once_any<'a>( fn rsplit_once_last<'a>(
&'a self, &'a self,
delimiters: &[&'static str], delimiters: &[&'static str],
) -> (&'a str, &'static str, &'a str) { ) -> (&'a str, &'static str, &'a str) {
for delimiter in delimiters { delimiters
if let Some((prefix, suffix)) = self.rsplit_once(delimiter) { .iter()
return (prefix, delimiter, suffix); .filter_map(|delimiter| self.rfind(delimiter).map(|i| (delimiter, i)))
} .max_by_key(|(_, i)| *i)
} .map(|(delimiter, _)| {
return ("", "", self); 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"); 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] #[test]
fn basic_get_significant_digits() { fn basic_get_significant_digits() {
let many_zeros = eval("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4"); let many_zeros = eval("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4");