use crate::evaluate_expression_with_context;
use crate::expression::parse_line_reference;
use crate::units::parse_unit;
use std::error::Error;
pub fn run_one_shot_mode(expression: &str) -> Result<(), Box<dyn Error>> {
print_formatted_expression(expression);
if let Some(result) = evaluate_expression_with_context(expression, &[], 0) {
println!(" = {}", result);
} else {
println!(" = (invalid expression)");
}
Ok(())
}
pub fn print_formatted_expression(text: &str) {
let mut current_pos = 0;
let chars: Vec<char> = text.chars().collect();
while current_pos < chars.len() {
if chars[current_pos].is_ascii_alphabetic() {
let start_pos = current_pos;
while current_pos < chars.len()
&& (chars[current_pos].is_ascii_alphabetic()
|| chars[current_pos].is_ascii_digit()
|| chars[current_pos] == '/')
{
current_pos += 1;
}
let word_text: String = chars[start_pos..current_pos].iter().collect();
if parse_line_reference(&word_text).is_some() {
print!("\x1b[95m{}\x1b[0m", word_text);
} else if word_text.to_lowercase() == "to" || word_text.to_lowercase() == "in" {
print!("\x1b[93m{}\x1b[0m", word_text);
} else if parse_unit(&word_text).is_some() {
print!("\x1b[92m{}\x1b[0m", word_text);
} else {
print!("{}", word_text);
}
} else if chars[current_pos].is_ascii_digit() || chars[current_pos] == '.' {
let start_pos = current_pos;
let mut has_digit = false;
let mut has_dot = false;
while current_pos < chars.len() {
let ch = chars[current_pos];
if ch.is_ascii_digit() {
has_digit = true;
current_pos += 1;
} else if ch == '.' && !has_dot {
has_dot = true;
current_pos += 1;
} else if ch == ',' {
current_pos += 1;
} else {
break;
}
}
if has_digit {
let number_text: String = chars[start_pos..current_pos].iter().collect();
print!("\x1b[94m{}\x1b[0m", number_text);
} else {
print!("{}", chars[start_pos]);
current_pos = start_pos + 1;
}
} else if "+-*/()".contains(chars[current_pos]) {
print!("\x1b[96m{}\x1b[0m", chars[current_pos]);
current_pos += 1;
} else {
print!("{}", chars[current_pos]);
current_pos += 1;
}
}
}