Skip to main content

rustapi_core/
validation.rs

1use crate::error::{ApiError, FieldError};
2
3/// Unified validation trait for synchronous validation
4///
5/// This trait allows uniform access to both `validator` (external) and
6/// `rustapi_validate::v2` (internal) validation engines.
7pub trait Validatable {
8    /// Perform synchronous validation
9    fn do_validate(&self) -> Result<(), ApiError>;
10}
11
12// Blanket implementation for types implementing the external validator::Validate trait
13#[cfg(feature = "legacy-validator")]
14impl<T: validator::Validate> Validatable for T {
15    fn do_validate(&self) -> Result<(), ApiError> {
16        match validator::Validate::validate(self) {
17            Ok(_) => Ok(()),
18            Err(e) => Err(convert_validator_errors(e)),
19        }
20    }
21}
22
23/// Helper to convert validator::ValidationErrors to rustapi_core::error::ApiError
24#[cfg(feature = "legacy-validator")]
25pub fn convert_validator_errors(errors: validator::ValidationErrors) -> ApiError {
26    let field_errors = errors
27        .field_errors()
28        .iter()
29        .flat_map(|(field, errs)| {
30            let field_name = field.to_string();
31            errs.iter().map(move |e| FieldError {
32                field: field_name.clone(),
33                code: e.code.to_string(),
34                message: e
35                    .message
36                    .clone()
37                    .map(|m| m.to_string())
38                    .unwrap_or_else(|| format!("Validation failed for field '{}'", field_name)),
39            })
40        })
41        .collect();
42    ApiError::validation(field_errors)
43}
44
45/// Helper to convert rustapi_validate::v2::ValidationErrors to rustapi_core::error::ApiError
46pub fn convert_v2_errors(errors: rustapi_validate::v2::ValidationErrors) -> ApiError {
47    let field_errors = errors
48        .fields
49        .iter()
50        .flat_map(|(field, errs)| {
51            let field_name = field.to_string();
52            errs.iter().map(move |e| FieldError {
53                field: field_name.clone(),
54                code: e.code.to_string(),
55                message: e.message.clone(),
56            })
57        })
58        .collect();
59    ApiError::validation(field_errors)
60}