skp_validator_rules/comparison/
required.rs1use skp_validator_core::{Rule, ValidationContext, ValidationErrors, ValidationError, ValidationResult};
4
5#[derive(Debug, Clone, Default)]
20pub struct RequiredRule {
21 pub message: Option<String>,
23}
24
25impl RequiredRule {
26 pub fn new() -> Self {
28 Self::default()
29 }
30
31 pub fn message(mut self, msg: impl Into<String>) -> Self {
33 self.message = Some(msg.into());
34 self
35 }
36
37 fn get_message(&self) -> String {
39 self.message.clone().unwrap_or_else(|| "This field is required".to_string())
40 }
41}
42
43impl Rule<str> for RequiredRule {
44 fn validate(&self, value: &str, _ctx: &ValidationContext) -> ValidationResult<()> {
45 if value.trim().is_empty() {
46 Err(ValidationErrors::from_iter([
47 ValidationError::root("required", self.get_message())
48 ]))
49 } else {
50 Ok(())
51 }
52 }
53
54 fn name(&self) -> &'static str {
55 "required"
56 }
57
58 fn default_message(&self) -> String {
59 "This field is required".to_string()
60 }
61}
62
63impl Rule<String> for RequiredRule {
64 fn validate(&self, value: &String, ctx: &ValidationContext) -> ValidationResult<()> {
65 <Self as Rule<str>>::validate(self, value.as_str(), ctx)
66 }
67
68 fn name(&self) -> &'static str {
69 "required"
70 }
71
72 fn default_message(&self) -> String {
73 "This field is required".to_string()
74 }
75}
76
77impl<T> Rule<Option<T>> for RequiredRule {
78 fn validate(&self, value: &Option<T>, _ctx: &ValidationContext) -> ValidationResult<()> {
79 if value.is_none() {
80 Err(ValidationErrors::from_iter([
81 ValidationError::root("required", self.get_message())
82 ]))
83 } else {
84 Ok(())
85 }
86 }
87
88 fn name(&self) -> &'static str {
89 "required"
90 }
91
92 fn default_message(&self) -> String {
93 "This field is required".to_string()
94 }
95}
96
97impl<T> Rule<Vec<T>> for RequiredRule {
98 fn validate(&self, value: &Vec<T>, _ctx: &ValidationContext) -> ValidationResult<()> {
99 if value.is_empty() {
100 Err(ValidationErrors::from_iter([
101 ValidationError::root("required", self.get_message())
102 ]))
103 } else {
104 Ok(())
105 }
106 }
107
108 fn name(&self) -> &'static str {
109 "required"
110 }
111
112 fn default_message(&self) -> String {
113 "This field is required".to_string()
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_required_string() {
123 let rule = RequiredRule::new();
124 let ctx = ValidationContext::default();
125
126 assert!(rule.validate("hello", &ctx).is_ok());
127 assert!(rule.validate("", &ctx).is_err());
128 assert!(rule.validate(" ", &ctx).is_err()); }
130
131 #[test]
132 fn test_required_option() {
133 let rule = RequiredRule::new();
134 let ctx = ValidationContext::default();
135
136 assert!(rule.validate(&Some(42), &ctx).is_ok());
137 assert!(rule.validate(&None::<i32>, &ctx).is_err());
138 }
139
140 #[test]
141 fn test_required_vec() {
142 let rule = RequiredRule::new();
143 let ctx = ValidationContext::default();
144
145 assert!(rule.validate(&vec![1, 2, 3], &ctx).is_ok());
146 assert!(rule.validate(&Vec::<i32>::new(), &ctx).is_err());
147 }
148
149 #[test]
150 fn test_custom_message() {
151 let rule = RequiredRule::new().message("Name cannot be empty");
152 let ctx = ValidationContext::default();
153
154 let result = rule.validate("", &ctx);
155 assert!(result.is_err());
156 let errors = result.unwrap_err();
157 assert!(errors.to_string().contains("Name cannot be empty"));
158 }
159}