use std::borrow::Cow;
use crate::Evaluation;
#[derive(Debug, PartialEq)]
pub enum Literal<'src> {
Number(f64),
String(Cow<'src, str>),
Boolean(bool),
Null,
}
impl<'src> Literal<'src> {
pub fn as_str(&self) -> Cow<'src, str> {
match self {
Literal::String(s) => s.clone(),
Literal::Number(n) => Cow::Owned(n.to_string()),
Literal::Boolean(b) => Cow::Owned(b.to_string()),
Literal::Null => Cow::Borrowed("null"),
}
}
pub(crate) fn consteval(&self) -> Evaluation {
match self {
Literal::String(s) => Evaluation::String(s.to_string()),
Literal::Number(n) => Evaluation::Number(*n),
Literal::Boolean(b) => Evaluation::Boolean(*b),
Literal::Null => Evaluation::Null,
}
}
}
#[cfg(test)]
mod tests {
use crate::{Error, Expr};
#[test]
fn test_evaluate_constant_literals() -> Result<(), Error> {
use crate::Evaluation;
let test_cases = &[
("'hello'", Evaluation::String("hello".to_string())),
("'world'", Evaluation::String("world".to_string())),
("42", Evaluation::Number(42.0)),
("3.14", Evaluation::Number(3.14)),
("true", Evaluation::Boolean(true)),
("false", Evaluation::Boolean(false)),
("null", Evaluation::Null),
("0xFF", Evaluation::Number(255.0)),
("0o10", Evaluation::Number(8.0)),
("1.5e2", Evaluation::Number(150.0)),
("+42", Evaluation::Number(42.0)),
(".5", Evaluation::Number(0.5)),
];
for (expr_str, expected) in test_cases {
let expr = Expr::parse(expr_str)?;
let result = expr.consteval().unwrap();
assert_eq!(result, *expected, "Failed for expression: {}", expr_str);
}
Ok(())
}
}