use std::fmt;
use super::operators;
use super::operators::Operator;
pub type Prec = f32;
#[derive(Debug, Clone)]
pub enum Component {
Variable(String),
Number(Prec),
Function {
operator: Operator,
values: Vec<Component>,
},
End,
}
impl fmt::Display for Component {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&self.to_text_prec(0))
}
}
impl Component {
fn to_text_prec(&self, prev_prec: i8) -> String {
match self {
Component::Variable(c) => c.to_string(),
Component::Number(f) => f.to_string(),
Component::Function { operator, values } => {
let op_value = operator.to_string();
if op_value.len() == 1 {
let prec = operators::get_precedence(Some(&op_value.chars().next().unwrap()));
format!(
"{}{} {} {}{}",
if prec < prev_prec { "(" } else { "" },
values[0].to_text_prec(prec),
op_value,
values[1].to_text_prec(prec),
if prec < prev_prec { ")" } else { "" }
)
} else {
let mut parameters = values[0].to_string();
for x in values.iter().skip(1) {
parameters = format!("{}, {}", parameters, x.to_string());
}
format!("{}({})", op_value, parameters)
}
}
_ => String::from(""),
}
}
pub fn to_float(&self) -> Option<Prec> {
match self {
Component::Number(f) => Some(*f),
_ => None,
}
}
}