oar_ocr/core/config/
derive.rs

1//! Utilities for ConfigValidator trait implementation.
2//!
3//! This module provides macros and utilities to make implementing ConfigValidator
4//! easier and more consistent across configuration types.
5
6/// Macro to implement ConfigValidator with basic validation patterns.
7///
8/// This macro provides a convenient way to implement ConfigValidator for configuration
9/// structs with common validation patterns.
10///
11/// # Example
12///
13/// ```rust,ignore
14/// use oar_ocr::core::config::{ConfigValidator, ConfigError};
15/// use oar_ocr::impl_config_validator;
16/// use serde::{Serialize, Deserialize};
17///
18/// #[derive(Debug, Clone, Serialize, Deserialize, Default)]
19/// pub struct MyConfig {
20///     pub confidence_threshold: f32,
21///     pub batch_size: usize,
22///     pub optional_threshold: Option<f32>,
23/// }
24///
25/// impl_config_validator!(MyConfig {
26///     confidence_threshold: range(0.0, 1.0),
27///     batch_size: min(1),
28///     optional_threshold: optional_range(0.0, 1.0),
29/// });
30/// ```
31#[macro_export]
32macro_rules! impl_config_validator {
33    ($type_name:ident { $($field:ident: $validation:tt),* $(,)? }) => {
34        impl $crate::core::config::ConfigValidator for $type_name {
35            fn validate(&self) -> Result<(), $crate::core::config::ConfigError> {
36                $(
37                    $crate::validate_field!(self, $field, $validation);
38                )*
39                Ok(())
40            }
41
42            fn get_defaults() -> Self
43            where
44                Self: Sized,
45            {
46                Self::default()
47            }
48        }
49    };
50}
51
52/// Helper macro for field validation.
53#[macro_export]
54macro_rules! validate_field {
55    ($self:expr, $field:ident, range($min:expr, $max:expr)) => {
56        if !($min..=$max).contains(&$self.$field) {
57            return Err($crate::core::config::ConfigError::InvalidConfig {
58                message: format!(
59                    "{} must be between {} and {}",
60                    stringify!($field),
61                    $min,
62                    $max
63                ),
64            });
65        }
66    };
67
68    ($self:expr, $field:ident, min($min_val:expr)) => {
69        if $self.$field < $min_val {
70            return Err($crate::core::config::ConfigError::InvalidConfig {
71                message: format!("{} must be at least {}", stringify!($field), $min_val),
72            });
73        }
74    };
75
76    ($self:expr, $field:ident, max($max_val:expr)) => {
77        if $self.$field > $max_val {
78            return Err($crate::core::config::ConfigError::InvalidConfig {
79                message: format!("{} must be at most {}", stringify!($field), $max_val),
80            });
81        }
82    };
83
84    ($self:expr, $field:ident, optional_range($min:expr, $max:expr)) => {
85        if let Some(value) = $self.$field {
86            if !($min..=$max).contains(&value) {
87                return Err($crate::core::config::ConfigError::InvalidConfig {
88                    message: format!(
89                        "{} must be between {} and {}",
90                        stringify!($field),
91                        $min,
92                        $max
93                    ),
94                });
95            }
96        }
97    };
98
99    ($self:expr, $field:ident, path) => {
100        $self.validate_model_path(&$self.$field)?;
101    };
102
103    ($self:expr, $field:ident, optional_path) => {
104        if let Some(ref path) = $self.$field {
105            $self.validate_model_path(path)?;
106        }
107    };
108}