use hurl_core::ast::{RegexValue, SourceInfo};
use crate::runner::regex::eval_regex_value;
use crate::runner::{RunnerError, RunnerErrorKind, Value, VariableSet};
pub fn eval_regex(
value: &Value,
regex: &RegexValue,
variables: &VariableSet,
source_info: SourceInfo,
assert: bool,
) -> Result<Option<Value>, RunnerError> {
let re = eval_regex_value(regex, variables)?;
match value {
Value::String(s) => match re.captures(s.as_str()) {
Some(captures) => match captures.get(1) {
Some(v) => Ok(Some(Value::String(v.as_str().to_string()))),
None => Ok(None),
},
None => Ok(None),
},
v => {
let kind = RunnerErrorKind::FilterInvalidInputType {
actual: v.kind().to_string(),
expected: "string".to_string(),
};
Err(RunnerError::new(source_info, kind, assert))
}
}
}
#[cfg(test)]
mod tests {
use hurl_core::ast::{
Filter, FilterValue, RegexValue, SourceInfo, Template, TemplateElement, Whitespace,
};
use hurl_core::reader::Pos;
use hurl_core::types::ToSource;
use crate::runner::filter::eval::eval_filter;
use crate::runner::{RunnerErrorKind, Value, VariableSet};
#[test]
fn eval_filter_regex() {
let variables = VariableSet::new();
let whitespace = Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(0, 0), Pos::new(0, 0)),
};
let filter = Filter {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 20)),
value: FilterValue::Regex {
space0: whitespace,
value: RegexValue::Template(Template::new(
None,
vec![TemplateElement::String {
value: "Hello (.*)!".to_string(),
source: "Hello (.*)!".to_source(),
}],
SourceInfo::new(Pos::new(1, 7), Pos::new(1, 20)),
)),
},
};
assert_eq!(
eval_filter(
&filter,
&Value::String("Hello Bob!".to_string()),
&variables,
false,
)
.unwrap()
.unwrap(),
Value::String("Bob".to_string())
);
let error = eval_filter(&filter, &Value::Bool(true), &variables, false)
.err()
.unwrap();
assert_eq!(
error.source_info,
SourceInfo::new(Pos::new(1, 1), Pos::new(1, 20))
);
assert_eq!(
error.kind,
RunnerErrorKind::FilterInvalidInputType {
actual: "boolean".to_string(),
expected: "string".to_string()
}
);
}
#[test]
fn eval_filter_invalid_regex() {
let variables = VariableSet::new();
let whitespace = Whitespace {
value: String::new(),
source_info: SourceInfo::new(Pos::new(0, 0), Pos::new(0, 0)),
};
let filter = Filter {
source_info: SourceInfo::new(Pos::new(1, 1), Pos::new(1, 20)),
value: FilterValue::Regex {
space0: whitespace,
value: RegexValue::Template(Template::new(
None,
vec![TemplateElement::String {
value: "???".to_string(),
source: "???".to_source(),
}],
SourceInfo::new(Pos::new(1, 7), Pos::new(1, 20)),
)),
},
};
let error = eval_filter(
&filter,
&Value::String("Hello Bob!".to_string()),
&variables,
false,
)
.err()
.unwrap();
assert_eq!(
error.source_info,
SourceInfo::new(Pos::new(1, 7), Pos::new(1, 20))
);
assert_eq!(error.kind, RunnerErrorKind::InvalidRegex);
}
}