diff --git a/src/formatting.rs b/src/formatting.rs index 7c207f5..a278c4b 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -3,15 +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('=') - .map(|(p, i)| (p, "= ", i)) - .unwrap_or_else(|| { - input - .rsplit_once('&') - .map(|(p, i)| (p, "& ", i)) - .unwrap_or(("", "", input)) - }); + let (prefix, deliminator, input) = input.rsplit_once_any(&["plus.minus ", "& ", "= "]); // no need to remove the character here, // as we ignore it in all other logic already @@ -39,6 +31,26 @@ pub fn pretty_eval(input: &str, max_digits: usize) -> Result { .replace('e', " * 10^")) } +trait StrExt { + fn rsplit_once_any<'a>( + &'a self, + delimiters: &[&'static str], + ) -> (&'a str, &'static str, &'a str); +} +impl StrExt for str { + fn rsplit_once_any<'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); + } +} + pub fn get_significant_digits(n: &Float) -> usize { let raw_string = n.to_string().replace('.', ""); @@ -98,6 +110,14 @@ mod tests { assert_eq!(pretty_eval("11.111111", 10).unwrap(), "11.111111"); } + #[test] + fn plus_minus() { + assert_eq!( + pretty_eval("y & = plus.minus sqrt(15.5) \\", 10).unwrap(), + "y & = plus.minus 3.937003937 \\" + ); + } + #[test] fn basic_get_significant_digits() { let many_zeros = eval("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4");