feat: generalize splitting for plus.minus

This commit is contained in:
electria 2026-10-14 16:50:51 -07:00
commit 702cf74647
Signed by: electria
SSH key fingerprint: SHA256:8LlB3ucPbBHqozqkhsNbaV5oG3SlzzqUj8FZDL6IPQs

View file

@ -3,15 +3,7 @@ use rug::Float;
use crate::nodes::{self, Error};
pub fn pretty_eval(input: &str, max_digits: usize) -> Result<String, Error> {
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<String, Error> {
.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");