use serde_json::Value;
use super::compare::Op;
use crate::control::placeholder::text;
use crate::metadata::{Constraints, OptionEntry, ParameterDef, ParameterType};
#[derive(Debug)]
pub(super) struct AssertParams {
pub value: String,
pub op: Op,
pub expected: String,
pub message: Option<String>,
}
impl AssertParams {
pub(super) fn read(params: &serde_json::Map<String, Value>) -> Result<Self, String> {
let value = params
.get("value")
.filter(|v| !v.is_null())
.ok_or("'value' is required: what the assert compares")?;
let op = params
.get("op")
.and_then(Value::as_str)
.ok_or("'op' is required: equals, not_equals, after or before")?;
Ok(Self {
value: text(value),
op: Op::parse(op)
.ok_or_else(|| format!("'op' \"{op}\" is not one of {}", Op::NAMES))?,
expected: params.get("expected").map(text).unwrap_or_default(),
message: params.get("message").map(text).filter(|m| !m.is_empty()),
})
}
}
impl AssertParams {
pub(super) fn describe(&self) -> String {
format!(
"\"{}\" {} \"{}\"",
self.value,
self.op.name(),
self.expected
)
}
}
pub(super) fn build_assert_parameters() -> Vec<ParameterDef> {
vec![
required(text_param(
"value",
"Value",
"What to check, usually a template such as {{node.<id>.<key>}}. With {{item.<key>}} \
or {{file}} (the file's name) it is checked once per incoming file, and no files \
means nothing to check.",
)),
required(op_param()),
text_param("expected", "Expected", "What the value is compared to."),
text_param(
"message",
"Message",
"Put before the reasons when the check fails, so the failure says what was checked.",
),
]
}
fn text_param(name: &str, label: &str, description: &str) -> ParameterDef {
ParameterDef {
name: name.to_string(),
label: label.to_string(),
description: description.to_string(),
param_type: ParameterType::String,
..Default::default()
}
}
fn required(param: ParameterDef) -> ParameterDef {
ParameterDef {
constraints: Some(Constraints {
min: None,
max: None,
required: true,
}),
..param
}
}
fn op_param() -> ParameterDef {
let option = |value: &str, label: &str| OptionEntry {
value: value.to_string(),
label: label.to_string(),
};
ParameterDef {
name: "op".to_string(),
label: "Comparison".to_string(),
description: "How value is compared to expected. after and before compare RFC 3339 times."
.to_string(),
param_type: ParameterType::Enum {
options: vec![
option("equals", "Equals"),
option("not_equals", "Does not equal"),
option("after", "Is after (time)"),
option("before", "Is before (time)"),
],
},
default: Some(serde_json::json!("equals")),
..Default::default()
}
}