Skip to main content

karbon_framework/validation/constraints/number/
not_null.rs

1use crate::validation::constraints::{Constraint, ConstraintResult, ConstraintViolation};
2
3/// Validates that a value is not null/empty.
4///
5/// Equivalent to Symfony's `NotNull` constraint.
6/// In Rust string context, this checks that the value is not empty.
7pub struct NotNull {
8    pub message: String,
9}
10
11impl Default for NotNull {
12    fn default() -> Self {
13        Self {
14            message: "This value should not be null.".to_string(),
15        }
16    }
17}
18
19impl NotNull {
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    pub fn with_message(mut self, message: impl Into<String>) -> Self {
25        self.message = message.into();
26        self
27    }
28}
29
30impl Constraint for NotNull {
31    fn validate(&self, value: &str) -> ConstraintResult {
32        if value.is_empty() {
33            return Err(ConstraintViolation::new(
34                self.name(),
35                &self.message,
36                value,
37            ));
38        }
39        Ok(())
40    }
41
42    fn name(&self) -> &'static str {
43        "NotNull"
44    }
45}
46
47/// Validates that an `Option<T>` is `Some`.
48#[allow(dead_code)]
49pub fn validate_not_null<T>(value: &Option<T>, message: Option<&str>) -> ConstraintResult {
50    if value.is_none() {
51        return Err(ConstraintViolation::new(
52            "NotNull",
53            message.unwrap_or("This value should not be null."),
54            "null",
55        ));
56    }
57    Ok(())
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_not_null_string() {
66        let constraint = NotNull::new();
67        assert!(constraint.validate("hello").is_ok());
68        assert!(constraint.validate("0").is_ok());
69        assert!(constraint.validate("").is_err());
70    }
71
72    #[test]
73    fn test_not_null_option() {
74        assert!(validate_not_null(&Some(42), None).is_ok());
75        assert!(validate_not_null(&Some(""), None).is_ok());
76        assert!(validate_not_null::<i32>(&None, None).is_err());
77    }
78
79    #[test]
80    fn test_custom_message() {
81        let constraint = NotNull::new().with_message("Ce champ est obligatoire.");
82        let err = constraint.validate("").unwrap_err();
83        assert_eq!(err.message, "Ce champ est obligatoire.");
84    }
85
86    #[test]
87    fn test_option_custom_message() {
88        let err = validate_not_null::<i32>(&None, Some("Valeur requise.")).unwrap_err();
89        assert_eq!(err.message, "Valeur requise.");
90    }
91}