use match_commutative::match_commutative; #[test] fn match_commutative_plus() { let operant1 = Operant::Str(Some("42".into())); let operant2 = Operant::Num(Some(1)); let operator = Operator::Plus; let result = match_commutative!( operant2, operator, operant1, Operant::Str(Some(op_str)), Operator::Plus, Operant::Num(Some(op_num)) => { op_str.parse::().unwrap() + op_num }, Operant::Str(_), Operator::Mult, Operant::Num(_) => { unreachable!() } non_commut { _,_,_ => { unreachable!() } } ); assert_eq!(43, result); } #[test] fn match_commutative_mult() { let operant1 = Operant::Str(Some("42".into())); let operant2 = Operant::Num(Some(2)); let operator = Operator::Mult; let result = match_commutative!( operant2, operator, operant1, Operant::Str(_), Operator::Plus, Operant::Num(_) => { unreachable!() }, Operant::Str(Some(op_str)), Operator::Mult, Operant::Num(Some(op_num)) => { op_str.parse::().unwrap() * op_num } non_commut { _,_,_ => { unreachable!() } } ); assert_eq!(84, result); } #[test] fn match_commutative_with_if_expr() { let operant1 = Operant::Str(Some("42".into())); let operant2 = Operant::Num(Some(2)); let operator = Operator::Mult; let result = match_commutative!( operant2, operator, operant1, Operant::Str(Some(op_str)), Operator::Plus, Operant::Num(_) if op_str.len() < 3 => { unreachable!() }, Operant::Str(Some(op_str)), Operator::Mult, Operant::Num(Some(op_num)) if op_str.len() < 3 => { op_str.parse::().unwrap() * op_num } non_commut { _,_,_ => { unreachable!() } } ); assert_eq!(84, result); } #[test] fn match_commutative_minus_within_non_commut_block() { let operant1 = Operant::Str(Some("42".into())); let operant2 = Operant::Num(Some(2)); let operator = Operator::Minus; let result = match_commutative!( &operant1, &operator, &operant2, Operant::Str(_), Operator::Plus, Operant::Num(_) => { unreachable!() } non_commut { Operant::Str(Some(op_str)), Operator::Minus, Operant::Num(Some(op_num)) => { op_str.parse::().unwrap() - op_num }, _,_,_ => { unreachable!() } } ); assert_eq!(40, result); let result = match_commutative!( operant2, operator, // operant1 and operant2 are swapped operant1, Operant::Str(_), Operator::Plus, Operant::Num(_) => { unreachable!() } non_commut { Operant::Num(Some(op_num)), Operator::Minus, Operant::Str(Some(op_str)) => { op_num - op_str.parse::().unwrap() }, _,_,_ => { unreachable!() } } ); assert_eq!(-40, result); } #[test] fn match_commutative_non_commut_block_has_if_expr() { let operant1 = Operant::Str(Some("42".into())); let operant2 = Operant::Num(Some(2)); let operator = Operator::Minus; let result = match_commutative!( &operant1, &operator, &operant2, Operant::Str(_), Operator::Plus, Operant::Num(_) => { unreachable!() } non_commut { Operant::Str(Some(op_str)), Operator::Minus, Operant::Num(Some(op_num)) if op_str.len() < 3 => { op_str.parse::().unwrap() - op_num }, _,_,_ => { unreachable!() } } ); assert_eq!(40, result); let result = match_commutative!( operant2, operator, // operant1 and operant2 are swapped operant1, Operant::Str(_), Operator::Plus, Operant::Num(_) => { unreachable!() } non_commut { Operant::Num(Some(op_num)), Operator::Minus, Operant::Str(Some(op_str)) if op_str.len() < 3 => { op_num - op_str.parse::().unwrap() }, Operant::Str(Some(op_str)), Operator::Minus, Operant::Num(Some(op_num)) if op_str.len() < 3 => { op_str.parse::().unwrap() - op_num }, _,_,_ => { unreachable!() } } ); assert_eq!(-40, result); } enum Operant { Str(Option), Num(Option), } enum Operator { Plus, Mult, Minus, }