From 4363916608ff63fb08be0dece11ca27c91e518d8 Mon Sep 17 00:00:00 2001 From: electria Date: Wed, 30 Sep 2026 17:40:31 -0700 Subject: [PATCH] refactor: split main.rs to support planned lib.rs --- src/formatting.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 101 +--------------------------------------------- 2 files changed, 102 insertions(+), 99 deletions(-) create mode 100644 src/formatting.rs diff --git a/src/formatting.rs b/src/formatting.rs new file mode 100644 index 0000000..9c494c3 --- /dev/null +++ b/src/formatting.rs @@ -0,0 +1,100 @@ +use std::str::FromStr; + +use rug::Float; + +use crate::nodes::Nodes; + +pub fn pretty_eval(mut input: String) -> String { + // no need to remove the characters here, + // as we ignore the them in all other logic already + let should_add_back_alignment = input.contains('&'); + let should_add_back_backslash = input.contains('\\'); + let leading_spaces = input.chars().take_while(|c| *c == ' ').count(); + + let should_add_back_equals = input + .find('=') + .inspect(|i| { + input.remove(*i); + }) + .is_some(); + + let result = Nodes::from_str(&input).unwrap().evaluate(); + let significant_digits = get_significant_digits(&result); + + format!( + "{:leading_spaces$}{}{result:.significant_digits$}{}", + ' ', + if should_add_back_equals && should_add_back_alignment { + "& = " + } else if should_add_back_equals { + "= " + } else if should_add_back_alignment { + "& " + } else { + "" + }, + if should_add_back_backslash { " \\" } else { "" } + ) +} +#[test] +fn test_character_readdition() { + assert_eq!(pretty_eval(" = 11".into()), " = 11"); + assert_eq!(pretty_eval(" &= 11".into()), " & = 11"); + assert_eq!(pretty_eval(" & 11".into()), " & 11"); + assert_eq!(pretty_eval(" & 11 \\".into()), " & 11 \\"); +} + +pub fn get_significant_digits(n: &Float) -> usize { + let raw_string: String = format!("{n}").chars().filter(|c| *c != '.').collect(); + + let mut consecutive_zeros = 0; + let mut consecutive_nines = 0; + for (i, c) in raw_string.char_indices() { + if c == '0' { + consecutive_zeros += 1; + } else { + consecutive_zeros = 0; + } + + if c == '9' { + consecutive_nines += 1; + } else { + consecutive_nines = 0; + } + + if consecutive_zeros >= 10 { + return i + 1 - consecutive_zeros; + } else if consecutive_nines >= 10 { + return i + 1 - consecutive_nines; + } + + if !raw_string[i..raw_string.len()].contains(|c| matches!(c, '1'..='9')) { + return i; + } + } + + // all digits are significant + raw_string.len() +} + +#[cfg(test)] +fn eval(s: &str) -> Float { + Nodes::from_str(s).unwrap().evaluate() +} + +#[test] +fn test_get_significant_digits() { + let many_zeros = eval("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4"); + assert_eq!(many_zeros.to_f64(), 117.48139); + let many_nines = eval("12.0096 + 15.9994 * 2"); + assert_eq!(many_nines.to_f64(), 44.0084); + let zero_nine_zero = eval("2+12321(5+123)"); + assert_eq!(zero_nine_zero.to_f64(), 1577090.0); + let test_4 = eval("12.0096 + 1.00784 * 3 + 12.0096 + 1.00784 * 2 + 15.9994 + 1.00784"); + assert_eq!(test_4.to_f64(), 46.06564); + + assert_eq!(get_significant_digits(&many_zeros), 8); + assert_eq!(get_significant_digits(&many_nines), 6); + assert_eq!(get_significant_digits(&zero_nine_zero), 6); + assert_eq!(get_significant_digits(&test_4), 7); +} diff --git a/src/main.rs b/src/main.rs index 0de49dc..e22e595 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,9 @@ use std::{ env, io::{self, Read}, - str::FromStr, }; -use rug::Float; - +mod formatting; mod nodes; fn main() { @@ -18,100 +16,5 @@ fn main() { } }; - println!("{}", parse_and_calc_humanreadable(input)); -} - -pub fn parse_and_calc_humanreadable(mut input: String) -> String { - // no need to remove the characters here, - // as we ignore the them in all other logic already - let should_add_back_alignment = input.contains('&'); - let should_add_back_backslash = input.contains('\\'); - let leading_spaces = input.chars().take_while(|c| *c == ' ').count(); - - let should_add_back_equals = input - .find('=') - .inspect(|i| { - input.remove(*i); - }) - .is_some(); - - let result = parse_and_calc(&input); - let significant_digits = get_significant_digits(&result); - - format!( - "{:leading_spaces$}{}{result:.significant_digits$}{}", - ' ', - if should_add_back_equals && should_add_back_alignment { - "& = " - } else if should_add_back_equals { - "= " - } else if should_add_back_alignment { - "& " - } else { - "" - }, - if should_add_back_backslash { " \\" } else { "" } - ) -} -#[test] -fn test_character_readdition() { - assert_eq!(parse_and_calc_humanreadable(" = 11".into()), " = 11"); - assert_eq!(parse_and_calc_humanreadable(" &= 11".into()), " & = 11"); - assert_eq!(parse_and_calc_humanreadable(" & 11".into()), " & 11"); - assert_eq!(parse_and_calc_humanreadable(" & 11 \\".into()), " & 11 \\"); -} - -pub fn parse_and_calc(s: &str) -> Float { - nodes::Nodes::from_str(s).unwrap().evaluate() -} - -pub fn get_significant_digits(n: &Float) -> usize { - let raw_string: String = format!("{n}").chars().filter(|c| *c != '.').collect(); - - let mut consecutive_zeros = 0; - let mut consecutive_nines = 0; - for (i, c) in raw_string.char_indices() { - if c == '0' { - consecutive_zeros += 1; - } else { - consecutive_zeros = 0; - } - - if c == '9' { - consecutive_nines += 1; - } else { - consecutive_nines = 0; - } - - if consecutive_zeros >= 10 { - return i + 1 - consecutive_zeros; - } else if consecutive_nines >= 10 { - return i + 1 - consecutive_nines; - } - - if !raw_string[i..raw_string.len()].contains(|c| matches!(c, '1'..='9')) { - return i; - } - } - - // all digits are significant - raw_string.len() -} - -#[test] -fn test_get_significant_digits() { - let many_zeros = parse_and_calc("14.00643 + 1.00784 * 4 + 35.446 + 15.9994 * 4"); - assert_eq!(many_zeros.to_f64(), 117.48139); - let many_nines = parse_and_calc("12.0096 + 15.9994 * 2"); - assert_eq!(many_nines.to_f64(), 44.0084); - let zero_nine_zero = parse_and_calc("2+12321(5+123)"); - assert_eq!(zero_nine_zero.to_f64(), 1577090.0); - let test_4 = - parse_and_calc("12.0096 + 1.00784 * 3 + 12.0096 + 1.00784 * 2 + 15.9994 + 1.00784"); - assert_eq!(test_4.to_f64(), 46.06564); - - assert_eq!(get_significant_digits(&many_zeros), 8); - assert_eq!(get_significant_digits(&many_nines), 6); - assert_eq!(get_significant_digits(&zero_nine_zero), 6); - assert_eq!(get_significant_digits(&test_4), 7); + println!("{}", formatting::pretty_eval(input)); }