diff --git a/src/formatting.rs b/src/formatting.rs index 7c207f5..bf321bc 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('.', ""); @@ -75,27 +87,36 @@ pub fn get_significant_digits(n: &Float) -> usize { #[cfg(test)] mod tests { use super::*; + const MAX_DIGITS: usize = 10; fn eval(s: &str) -> Float { crate::nodes::eval(s).unwrap() } #[test] fn character_readdition() { - assert_eq!(pretty_eval(" = 11", 10).unwrap(), " = 11"); - assert_eq!(pretty_eval(" &= 11", 10).unwrap(), " &= 11"); - assert_eq!(pretty_eval(" & 11", 10).unwrap(), " & 11"); - assert_eq!(pretty_eval(" & 11 \\", 10).unwrap(), " & 11 \\"); + assert_eq!(pretty_eval(" = 11", MAX_DIGITS).unwrap(), " = 11"); + assert_eq!(pretty_eval(" &= 11", MAX_DIGITS).unwrap(), " &= 11"); + assert_eq!(pretty_eval(" & 11", MAX_DIGITS).unwrap(), " & 11"); + assert_eq!(pretty_eval(" & 11 \\", MAX_DIGITS).unwrap(), " & 11 \\"); } #[test] fn basic_output_up_to_999() { - assert_eq!(pretty_eval("1", 10).unwrap(), "1"); - assert_eq!(pretty_eval("10", 10).unwrap(), "10"); - assert_eq!(pretty_eval("100", 10).unwrap(), "100"); - assert_eq!(pretty_eval("999", 10).unwrap(), "999"); - assert_eq!(pretty_eval("1000", 10).unwrap(), "1 * 10^3"); + assert_eq!(pretty_eval("1", MAX_DIGITS).unwrap(), "1"); + assert_eq!(pretty_eval("10", MAX_DIGITS).unwrap(), "10"); + assert_eq!(pretty_eval("100", MAX_DIGITS).unwrap(), "100"); + assert_eq!(pretty_eval("999", MAX_DIGITS).unwrap(), "999"); + assert_eq!(pretty_eval("1000", MAX_DIGITS).unwrap(), "1 * 10^3"); - assert_eq!(pretty_eval("11.111111", 10).unwrap(), "11.111111"); + assert_eq!(pretty_eval("11.111111", MAX_DIGITS).unwrap(), "11.111111"); + } + + #[test] + fn plus_minus() { + assert_eq!( + pretty_eval("y & = plus.minus sqrt(15.5) \\", MAX_DIGITS).unwrap(), + "y & = plus.minus 3.937003937 \\" + ); } #[test]