From b7187e210ae7e794c87ae2f76d0f212e5d716b15 Mon Sep 17 00:00:00 2001 From: troido Date: Mon, 28 Sep 2020 17:55:41 +0200 Subject: added type validation for parameters --- src/parameterexpression.rs | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'src/parameterexpression.rs') diff --git a/src/parameterexpression.rs b/src/parameterexpression.rs index c96bd93..dfba562 100644 --- a/src/parameterexpression.rs +++ b/src/parameterexpression.rs @@ -25,38 +25,43 @@ pub enum ParameterExpression { TemplateName } +pub enum EvaluationError { + MissingArgument(String), + Other(String) +} + impl ParameterExpression { - pub fn evaluate(&self, arguments: &HashMap<&str, Parameter>, template: &Template) -> Option { + pub fn evaluate(&self, arguments: &HashMap, template: &Template) -> Result { self.evaluate_(arguments, template, 0) } - fn evaluate_(&self, arguments: &HashMap<&str, Parameter>, template: &Template, nesting: usize) -> Option { + fn evaluate_(&self, arguments: &HashMap, template: &Template, nesting: usize) -> Result { if nesting > MAX_NESTING { - return None; + return Err(EvaluationError::Other("Maximum nesting reached in parameter evaluation".to_string())); } match self { Self::Constant(val) => { - Some(val.clone()) + Ok(val.clone()) } Self::List(values) => { - Some(Parameter::List(values.iter().map(|v| v.evaluate_(arguments, template, nesting+1)).collect::>>()?)) + Ok(Parameter::List(values.iter().map(|v| v.evaluate_(arguments, template, nesting+1)).collect::, EvaluationError>>()?)) } Self::Template{name, kwargs, save, clan} => { - Some(Parameter::Template(Template{ + Ok(Parameter::Template(Template{ name: name.clone(), save: *save, kwargs: kwargs .iter() .map( |(k, v)| - Some((k.clone(), v.evaluate_(arguments, template, nesting+1)?))) - .collect::>>()?, + Ok((k.clone(), v.evaluate_(arguments, template, nesting+1)?))) + .collect::, EvaluationError>>()?, clan: clan.clone() })) } Self::Argument(argname) => { - Some(arguments.get(argname.as_str())?.clone()) + Ok(arguments.get(argname.as_str()).ok_or(EvaluationError::MissingArgument(argname.to_string()))?.clone()) } Self::Random(options) => { let r = rand::thread_rng().gen_range(0, options.len()); @@ -68,10 +73,10 @@ impl ParameterExpression { if let Parameter::String(s) = option.evaluate_(arguments, template, nesting+1)? { string.push_str(&s); } else { - return None; + return Err(EvaluationError::Other(format!("string concatenation value not a string: {:?}", option))); } } - Some(Parameter::String(string)) + Ok(Parameter::String(string)) } Self::If(condition, thenval, elseval) => { if let Parameter::Bool(b) = condition.evaluate_(arguments, template, nesting+1)? { @@ -81,11 +86,11 @@ impl ParameterExpression { elseval.evaluate_(arguments, template, nesting+1) } } else { - None + return Err(EvaluationError::Other(format!("if condition not a bool: {:?}", condition))) } } - Self::TemplateSelf => Some(Parameter::Template(template.clone())), - Self::TemplateName => Some(Parameter::String(template.name.0.clone())), + Self::TemplateSelf => Ok(Parameter::Template(template.clone())), + Self::TemplateName => Ok(Parameter::String(template.name.0.clone())), } } -- cgit