diff options
Diffstat (limited to 'src/format/mod.rs')
-rw-r--r-- | src/format/mod.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/format/mod.rs b/src/format/mod.rs new file mode 100644 index 0000000..4ac5612 --- /dev/null +++ b/src/format/mod.rs | |||
@@ -0,0 +1,86 @@ | |||
1 | use crate::CONFIGURATION; | ||
2 | use crate::error::{ | ||
3 | CalcError, | ||
4 | Math | ||
5 | }; | ||
6 | |||
7 | pub fn autobalance_parens(input: &str) -> Result<String, CalcError> { | ||
8 | let mut balanced = String::from(input); | ||
9 | let mut left_parens = 0; | ||
10 | let mut right_parens = 0; | ||
11 | for letter in input.chars() { | ||
12 | if letter == '(' { | ||
13 | left_parens += 1; | ||
14 | } else if letter == ')' { | ||
15 | right_parens += 1; | ||
16 | } | ||
17 | } | ||
18 | |||
19 | if left_parens > right_parens { | ||
20 | let extras = ")".repeat(left_parens - right_parens); | ||
21 | balanced.push_str(&extras[..]); | ||
22 | Ok(balanced) | ||
23 | } else if left_parens < right_parens { | ||
24 | return Err(CalcError::Syntax("Mismatched parentheses!".into())) | ||
25 | } else { | ||
26 | Ok(balanced) | ||
27 | } | ||
28 | } | ||
29 | |||
30 | fn radix_fmt(number: f64, obase: usize) -> Result<String, CalcError> { | ||
31 | if obase > 36 { | ||
32 | return Err(CalcError::Math(Math::UnknownBase)); | ||
33 | } | ||
34 | |||
35 | let table: Vec<char> = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".chars().collect(); | ||
36 | |||
37 | // format integral part of float | ||
38 | let mut integral = number.trunc() as i64; | ||
39 | let mut obase_int = String::new(); | ||
40 | while integral >= obase as i64 { | ||
41 | obase_int.push(table[(integral % obase as i64) as usize]); | ||
42 | integral /= obase as i64; | ||
43 | } | ||
44 | obase_int.push(table[integral as usize]); | ||
45 | if number.is_sign_negative() { | ||
46 | obase_int.push('-'); | ||
47 | } | ||
48 | let obase_int = obase_int.chars().rev().collect::<String>(); | ||
49 | |||
50 | // format fractional part of float | ||
51 | let mut fract = number.abs().fract(); | ||
52 | let mut obase_fract = String::new(); | ||
53 | let mut i = 0; | ||
54 | loop { | ||
55 | fract *= obase as f64; | ||
56 | obase_fract.push(table[fract.trunc() as usize]); | ||
57 | i += 1; | ||
58 | if fract.fract() == 0. || i > 10 { | ||
59 | break; | ||
60 | } | ||
61 | fract = fract.fract(); | ||
62 | } | ||
63 | Ok(format!("{}.{}", obase_int, obase_fract)) | ||
64 | } | ||
65 | |||
66 | fn thousand_sep(inp: &str) -> String { | ||
67 | let mut result_string = String::new(); | ||
68 | for (i,c) in inp.to_string().chars().rev().enumerate() { | ||
69 | if i % 3 == 0 && i != 0 && c.to_string() != "-" { | ||
70 | result_string.push(','); | ||
71 | } | ||
72 | result_string.push(c) | ||
73 | } | ||
74 | result_string.chars().rev().collect::<String>() | ||
75 | } | ||
76 | |||
77 | pub fn pprint(ans: f64) { | ||
78 | let ans_string = radix_fmt(ans, CONFIGURATION.base).unwrap(); | ||
79 | let ans_vector: Vec<&str> = ans_string.split(".").collect(); | ||
80 | match ans_vector.len() { | ||
81 | 1 => println!("{:>10}", thousand_sep(ans_vector[0])), | ||
82 | 2 => println!("{:>10}.{}", thousand_sep(ans_vector[0]),ans_vector[1]), | ||
83 | _ => unreachable!("N-nani?!") | ||
84 | } | ||
85 | } | ||
86 | |||