1#![feature(box_syntax, box_patterns)]23use jsonnet_parser::*;45#[derive(Debug, Clone, PartialEq)]6pub enum Val {7 Str(String),8 Num(f64),9}1011pub fn evaluate(expr: &Expr) -> Val {12 use Expr::*;13 match expr {14 Parened(e) => evaluate(e),15 Str(v) => Val::Str(v.clone()),16 Num(v) => Val::Num(*v),17 BinaryOp(v1, o, v2) => match (evaluate(v1), o, evaluate(v2)) {18 (Val::Str(v1), BinaryOpType::Add, Val::Str(v2)) => Val::Str(v1 + &v2),19 (Val::Str(v1), BinaryOpType::Mul, Val::Num(v2)) => {20 Val::Str(v1.repeat(v2 as usize))21 },22 (Val::Num(v1), BinaryOpType::Add, Val::Num(v2)) => Val::Num(v1 + v2),23 (Val::Num(v1), BinaryOpType::Mul, Val::Num(v2)) => Val::Num(v1 * v2),24 _ => panic!("Can't evaluate binary op: {:?} {:?} {:?}", v1, o, v2),25 },26 _ => panic!("Can't evaluate: {:?}", expr),27 }28}2930#[cfg(test)]31pub mod tests {32 use super::{evaluate, Val};33 use jsonnet_parser::parse;34 #[test]35 fn math_evaluation() {36 assert_eq!(evaluate(&parse("2+2*2").unwrap()), Val::Num(6.0));37 }3839 #[test]40 fn math_evaluation_with_parened() {41 assert_eq!(evaluate(&parse("3+(2+2*2)").unwrap()), Val::Num(9.0));42 }4344 #[test]45 fn string_concat() {46 assert_eq!(47 evaluate(&parse("\"Hello\"+\"World\"").unwrap()),48 Val::Str("HelloWorld".to_owned()),49 );50 }5152 #[test]53 fn string_repeat() {54 assert_eq!(55 evaluate(&parse("\"Hello\"*3").unwrap()),56 Val::Str("HelloHelloHello".to_owned()),57 );58 }59}