use hurl_core::ast::{Placeholder, Template, TemplateElement};
use super::error::RunnerError;
use super::expr;
use super::variable::VariableSet;
pub fn eval_template(template: &Template, variables: &VariableSet) -> Result<String, RunnerError> {
let Template { elements, .. } = template;
let mut value = String::new();
for elem in elements {
match eval_template_element(elem, variables) {
Ok(v) => value.push_str(v.as_str()),
Err(e) => return Err(e),
}
}
Ok(value)
}
fn eval_template_element(
template_element: &TemplateElement,
variables: &VariableSet,
) -> Result<String, RunnerError> {
match template_element {
TemplateElement::String { value, .. } => Ok(value.clone()),
TemplateElement::Placeholder(Placeholder { expr, .. }) => expr::render(expr, variables),
}
}
#[cfg(test)]
mod tests {
use hurl_core::ast::{Expr, ExprKind, SourceInfo, Variable, Whitespace};
use hurl_core::reader::Pos;
use hurl_core::types::ToSource;
use super::*;
use crate::runner::{Number, RunnerErrorKind, Value};
fn template_element_expression() -> TemplateElement {
TemplateElement::Placeholder(Placeholder {
space0: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 3)),
},
expr: Expr {
kind: ExprKind::Variable(Variable {
name: "name".to_string(),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 7)),
}),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 7)),
},
space1: Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(1, 3), Pos::new(1, 7)),
},
})
}
#[test]
fn test_template_element() {
let variables = VariableSet::new();
assert_eq!(
eval_template_element(
&TemplateElement::String {
value: "World".to_string(),
source: "World".to_source(),
},
&variables
)
.unwrap(),
"World".to_string()
);
let mut variables = VariableSet::new();
variables.insert("name".to_string(), Value::String("World".to_string()));
assert_eq!(
eval_template_element(&template_element_expression(), &variables).unwrap(),
"World".to_string()
);
}
#[test]
fn test_template_element_error() {
let mut variables = VariableSet::new();
variables.insert(
"name".to_string(),
Value::List(vec![
Value::Number(Number::Integer(1)),
Value::Number(Number::Integer(2)),
]),
);
let error = eval_template_element(&template_element_expression(), &variables)
.err()
.unwrap();
assert_eq!(
error.source_info,
SourceInfo::new(Pos::new(1, 3), Pos::new(1, 7))
);
assert_eq!(
error.kind,
RunnerErrorKind::UnrenderableExpression {
value: "[1,2]".to_string()
}
);
}
}