toasty_core/schema/app/constraint/
length.rs

1use super::Constraint;
2
3use crate::{Result, stmt};
4
5/// A length constraint for string fields.
6///
7/// Enforces minimum and/or maximum character-count bounds on a string value.
8/// Either bound can be `None` to leave that side unconstrained.
9///
10/// # Examples
11///
12/// ```
13/// use toasty_core::schema::app::ConstraintLength;
14///
15/// let c = ConstraintLength { min: Some(1), max: Some(255) };
16/// assert_eq!(c.min, Some(1));
17/// assert_eq!(c.max, Some(255));
18/// ```
19#[derive(Debug, Clone)]
20pub struct ConstraintLength {
21    /// The minimum length of the field. `None` means no lower bound.
22    pub min: Option<u64>,
23
24    /// The maximum length of the field. `None` means no upper bound.
25    pub max: Option<u64>,
26}
27impl ConstraintLength {
28    pub(crate) fn check(&self, expr: &crate::stmt::Entry<'_>) -> Result<()> {
29        let Some(stmt::Value::String(value)) = expr.as_value() else {
30            return Ok(());
31        };
32
33        let value_len = value.len();
34        let min = self.min.map(|m| m as usize);
35        let max = self.max.map(|m| m as usize);
36
37        // Check minimum length
38        if let Some(min_val) = min
39            && value_len < min_val
40        {
41            return Err(crate::Error::validation_length(value_len, min, max));
42        }
43
44        // Check maximum length
45        if let Some(max_val) = max
46            && value_len > max_val
47        {
48            return Err(crate::Error::validation_length(value_len, min, max));
49        }
50
51        Ok(())
52    }
53}
54
55impl From<ConstraintLength> for Constraint {
56    fn from(length: ConstraintLength) -> Self {
57        Constraint::Length(length)
58    }
59}