pub(crate) mod any;
pub(crate) mod cel;
pub(crate) mod embedded;
pub(crate) mod enum_check;
pub(crate) mod field;
pub(crate) mod list;
pub(crate) mod map;
pub(crate) mod message;
pub(crate) mod oneof;
pub(crate) mod value;
pub(crate) mod wrapper;
use prost_reflect::DynamicMessage;
use crate::config::ValidationConfig;
use crate::error::Error;
pub(crate) fn prepend_rule_prefix(result: Result<(), Error>, prefix: &str) -> Result<(), Error> {
match result {
Ok(()) => Ok(()),
Err(Error::Validation(mut ve)) => {
for violation in ve.violations_mut() {
violation.prepend_rule_path(prefix);
}
Err(Error::Validation(ve))
}
Err(other) => Err(other),
}
}
pub(crate) trait Evaluator: Send + Sync {
fn tautology(&self) -> bool;
fn evaluate(
&self,
msg: &DynamicMessage,
val: &prost_reflect::Value,
cfg: &ValidationConfig,
) -> Result<(), Error>;
}
pub(crate) trait MessageEvaluator: Send + Sync {
fn tautology(&self) -> bool;
fn evaluate_message(&self, msg: &DynamicMessage, cfg: &ValidationConfig) -> Result<(), Error>;
}
pub(crate) struct Evaluators(pub Vec<Box<dyn Evaluator>>);
impl Evaluators {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn push(&mut self, eval: Box<dyn Evaluator>) {
if !eval.tautology() {
self.0.push(eval);
}
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for Evaluators {
fn default() -> Self {
Self::new()
}
}
impl Evaluator for Evaluators {
fn tautology(&self) -> bool {
self.0.iter().all(|e| e.tautology())
}
fn evaluate(
&self,
msg: &DynamicMessage,
val: &prost_reflect::Value,
cfg: &ValidationConfig,
) -> Result<(), Error> {
let mut acc: Option<Error> = None;
for eval in &self.0 {
let result = eval.evaluate(msg, val, cfg);
let (cont, new_acc) = crate::error::merge_violations(acc, result, cfg.fail_fast);
acc = new_acc;
if !cont {
break;
}
}
match acc {
Some(err) => Err(err),
None => Ok(()),
}
}
}
pub(crate) struct MessageEvaluators(pub Vec<Box<dyn MessageEvaluator>>);
impl MessageEvaluators {
pub fn new() -> Self {
Self(Vec::new())
}
pub fn push(&mut self, eval: Box<dyn MessageEvaluator>) {
if !eval.tautology() {
self.0.push(eval);
}
}
}
impl Default for MessageEvaluators {
fn default() -> Self {
Self::new()
}
}
impl MessageEvaluator for MessageEvaluators {
fn tautology(&self) -> bool {
self.0.iter().all(|e| e.tautology())
}
fn evaluate_message(&self, msg: &DynamicMessage, cfg: &ValidationConfig) -> Result<(), Error> {
let mut acc: Option<Error> = None;
for eval in &self.0 {
let result = eval.evaluate_message(msg, cfg);
let (cont, new_acc) = crate::error::merge_violations(acc, result, cfg.fail_fast);
acc = new_acc;
if !cont {
break;
}
}
match acc {
Some(err) => Err(err),
None => Ok(()),
}
}
}