this/core/validation/
config.rs1use anyhow::Result;
7use serde_json::Value;
8use std::collections::HashMap;
9
10type ValidatorFn = Box<dyn Fn(&str, &Value) -> Result<(), String> + Send + Sync>;
12
13type FilterFn = Box<dyn Fn(&str, Value) -> Result<Value> + Send + Sync>;
15
16pub struct EntityValidationConfig {
18 pub entity_type: String,
20
21 validators: HashMap<String, Vec<ValidatorFn>>,
23
24 filters: HashMap<String, Vec<FilterFn>>,
26}
27
28impl EntityValidationConfig {
29 pub fn new(entity_type: &str) -> Self {
31 Self {
32 entity_type: entity_type.to_string(),
33 validators: HashMap::new(),
34 filters: HashMap::new(),
35 }
36 }
37
38 pub fn add_validator<F>(&mut self, field: &str, validator: F)
40 where
41 F: Fn(&str, &Value) -> Result<(), String> + Send + Sync + 'static,
42 {
43 self.validators
44 .entry(field.to_string())
45 .or_default()
46 .push(Box::new(validator));
47 }
48
49 pub fn add_filter<F>(&mut self, field: &str, filter: F)
51 where
52 F: Fn(&str, Value) -> Result<Value> + Send + Sync + 'static,
53 {
54 self.filters
55 .entry(field.to_string())
56 .or_default()
57 .push(Box::new(filter));
58 }
59
60 pub fn validate_and_filter(&self, mut payload: Value) -> Result<Value, Vec<String>> {
64 let mut errors = Vec::new();
65
66 if let Some(obj) = payload.as_object_mut() {
68 for (field, value) in obj.iter_mut() {
69 if let Some(field_filters) = self.filters.get(field) {
70 for filter in field_filters {
71 match filter(field, value.clone()) {
72 Ok(filtered) => *value = filtered,
73 Err(e) => {
74 errors.push(format!("Erreur de filtrage sur '{}': {}", field, e));
75 }
76 }
77 }
78 }
79 }
80 }
81
82 if let Some(obj) = payload.as_object() {
84 for (field, value) in obj.iter() {
85 if let Some(field_validators) = self.validators.get(field) {
86 for validator in field_validators {
87 if let Err(e) = validator(field, value) {
88 errors.push(e);
89 }
90 }
91 }
92 }
93 }
94
95 if errors.is_empty() {
96 Ok(payload)
97 } else {
98 Err(errors)
99 }
100 }
101}