difftreelog
feat(evaluator) argument parsing macro
in: master
2 files changed
crates/jsonnet-evaluator/src/error.rsdiffbeforeafterboth6pub enum Error {6pub enum Error {7 VariableIsNotDefined(String),7 VariableIsNotDefined(String),8 TypeMismatch(&'static str, Vec<ValType>, ValType),8 TypeMismatch(&'static str, Vec<ValType>, ValType),9 IntristicArgumentReorderingIsNotSupportedYet,9 NoSuchField(Rc<str>),10 NoSuchField(Rc<str>),101111 UnknownVariable(Rc<str>),12 UnknownVariable(Rc<str>),crates/jsonnet-evaluator/src/function.rsdiffbeforeafterboth94 Ok(body_ctx.unwrap_or(ctx).extend(out, None, None, None)?)94 Ok(body_ctx.unwrap_or(ctx).extend(out, None, None, None)?)95}95}9697#[macro_export]98macro_rules! parse_args {99 ($ctx: expr, $fn_name: expr, $args: expr, $total_args: expr, [100 $($id: expr, $name: ident $(: [$($p: path)|+] $(!! $a: path)?)?, $nt: expr);+ $(;)?101 ], $handler:block) => {{102 use crate::error::Error;103 let args = $args;104 if args.len() > $total_args {105 create_error(Error::TooManyArgsFunctionHas($total_args))?;106 }107 $(108 if args.len() <= $id {109 create_error(Error::FunctionParameterNotBoundInCall(stringify!($name).into()))?;110 }111 let $name = &args[$id];112 if $name.0.is_some() {113 if $name.0.as_ref().unwrap() != stringify!($name) {114 create_error(Error::IntristicArgumentReorderingIsNotSupportedYet)?;115 }116 }117 let $name = evaluate($ctx.clone(), &$name.1)?;118 $(119 match $name {120 $($p(_))|+ => {},121 _ => create_error(Error::TypeMismatch(concat!($fn_name, " ", stringify!($id), "nd argument"), $nt, $name.value_type()?))?,122 };123 $(124 let $name = match $name {125 $a(v) => v,126 _ => create_error(Error::TypeMismatch(concat!($fn_name, " ", stringify!($id), "nd argument"), $nt, $name.value_type()?))?,127 };128 )*129 )*130 )+131 $handler132 }};133}134135#[test]136fn test() -> Result<()> {137 use jsonnet_parser::*;138 use crate::val::ValType;139 let state = crate::EvaluationState::default();140 let evaluator = state.with_stdlib();141 let ctx = evaluator.create_default_context()?;142 evaluator.run_in_state(|| {143 parse_args!(ctx, "test", ArgsDesc(vec![144 Arg(None, el!(Expr::Num(2.0))),145 Arg(Some("b".into()), el!(Expr::Num(1.0))),146 ]), 2, [147 0, a: [Val::Num]!!Val::Num, vec![ValType::Num];148 1, b: [Val::Num]!!Val::Num, vec![ValType::Num];149 ], {150 assert!((a - 2.0).abs() <= f64::EPSILON);151 assert!((b - 1.0).abs() <= f64::EPSILON);152 });153 Ok(())154 })155}96156