use prost_reflect::DynamicMessage;
use crate::config::ValidationConfig;
use crate::error::{self, Error};
use super::Evaluator;
use super::prepend_rule_prefix;
use super::value::ValueEval;
pub(crate) struct ListEval {
pub item_rules: ValueEval,
}
impl Evaluator for ListEval {
fn tautology(&self) -> bool {
self.item_rules.tautology()
}
fn evaluate(
&self,
msg: &DynamicMessage,
val: &prost_reflect::Value,
cfg: &ValidationConfig,
) -> Result<(), Error> {
let Some(list) = val.as_list() else {
return Ok(());
};
let mut acc: Option<Error> = None;
for (i, item) in list.iter().enumerate() {
let item_path = format!("[{i}]");
let (direct, nested) = self
.item_rules
.evaluate_value_split(msg, item, cfg, &item_path);
let direct = prepend_rule_prefix(direct, "repeated.items");
let (cont, new_acc) = error::merge_violations(acc, direct, cfg.fail_fast);
acc = new_acc;
if !cont {
break;
}
let (cont, new_acc) = error::merge_violations(acc, nested, cfg.fail_fast);
acc = new_acc;
if !cont {
break;
}
}
match acc {
Some(err) => Err(err),
None => Ok(()),
}
}
}