1use crate::evaluate_expression_with_context;
4use crate::expression::parse_line_reference;
5use crate::units::parse_unit;
6use std::error::Error;
7
8pub fn run_one_shot_mode(expression: &str) -> Result<(), Box<dyn Error>> {
10 print_formatted_expression(expression);
12
13 if let Some(result) = evaluate_expression_with_context(expression, &[], 0) {
15 println!(" = {}", result);
16 } else {
17 println!(" = (invalid expression)");
18 }
19
20 Ok(())
21}
22
23pub fn print_formatted_expression(text: &str) {
25 let mut current_pos = 0;
27 let chars: Vec<char> = text.chars().collect();
28
29 while current_pos < chars.len() {
30 if chars[current_pos].is_ascii_alphabetic() {
31 let start_pos = current_pos;
33
34 while current_pos < chars.len()
35 && (chars[current_pos].is_ascii_alphabetic()
36 || chars[current_pos].is_ascii_digit()
37 || chars[current_pos] == '/')
38 {
39 current_pos += 1;
40 }
41
42 let word_text: String = chars[start_pos..current_pos].iter().collect();
43
44 if parse_line_reference(&word_text).is_some() {
46 print!("\x1b[95m{}\x1b[0m", word_text);
48 } else if word_text.to_lowercase() == "to" || word_text.to_lowercase() == "in" {
49 print!("\x1b[93m{}\x1b[0m", word_text);
51 } else if parse_unit(&word_text).is_some() {
52 print!("\x1b[92m{}\x1b[0m", word_text);
54 } else {
55 print!("{}", word_text);
56 }
57 } else if chars[current_pos].is_ascii_digit() || chars[current_pos] == '.' {
58 let start_pos = current_pos;
60 let mut has_digit = false;
61 let mut has_dot = false;
62
63 while current_pos < chars.len() {
64 let ch = chars[current_pos];
65 if ch.is_ascii_digit() {
66 has_digit = true;
67 current_pos += 1;
68 } else if ch == '.' && !has_dot {
69 has_dot = true;
70 current_pos += 1;
71 } else if ch == ',' {
72 current_pos += 1;
73 } else {
74 break;
75 }
76 }
77
78 if has_digit {
79 let number_text: String = chars[start_pos..current_pos].iter().collect();
80 print!("\x1b[94m{}\x1b[0m", number_text);
82 } else {
83 print!("{}", chars[start_pos]);
84 current_pos = start_pos + 1;
85 }
86 } else if "+-*/()".contains(chars[current_pos]) {
87 print!("\x1b[96m{}\x1b[0m", chars[current_pos]);
89 current_pos += 1;
90 } else {
91 print!("{}", chars[current_pos]);
92 current_pos += 1;
93 }
94 }
95}