wasm_dbms_api/dbms/validate/
strlen.rs1use crate::prelude::{DbmsError, Validate, Value};
2
3pub struct MaxStrlenValidator(pub usize);
18
19impl Validate for MaxStrlenValidator {
20 fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
21 let Value::Text(text) = value else {
22 return Err(DbmsError::Validation("Value is not a `Text`".to_string()));
23 };
24
25 let len = text.0.chars().count();
26
27 if len <= self.0 {
28 Ok(())
29 } else {
30 Err(DbmsError::Validation(format!(
31 "String length {} exceeds maximum allowed length of {}",
32 len, self.0
33 )))
34 }
35 }
36}
37
38pub struct MinStrlenValidator(pub usize);
52
53impl Validate for MinStrlenValidator {
54 fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
55 let Value::Text(text) = value else {
56 return Err(DbmsError::Validation("Value is not a `Text`".to_string()));
57 };
58
59 let len = text.0.chars().count();
60
61 if len >= self.0 {
62 Ok(())
63 } else {
64 Err(DbmsError::Validation(format!(
65 "String length {} is less than minimum required length of {}",
66 len, self.0
67 )))
68 }
69 }
70}
71
72pub struct RangeStrlenValidator(pub usize, pub usize);
89
90impl Validate for RangeStrlenValidator {
91 fn validate(&self, value: &Value) -> crate::prelude::DbmsResult<()> {
92 let Value::Text(text) = value else {
93 return Err(DbmsError::Validation("Value is not a `Text`".to_string()));
94 };
95
96 let len = text.0.chars().count();
97
98 if len >= self.0 && len <= self.1 {
99 Ok(())
100 } else {
101 Err(DbmsError::Validation(format!(
102 "String length {} is not within the allowed range of {} to {}",
103 len, self.0, self.1
104 )))
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111
112 use super::*;
113 use crate::prelude::Text;
114
115 #[test]
116 fn test_max_strlen_validator() {
117 let validator = MaxStrlenValidator(5);
118
119 let valid_value = Value::Text(Text("Hello".to_string()));
120 let invalid_value = Value::Text(Text("Hello, World!".to_string()));
121
122 assert!(validator.validate(&valid_value).is_ok());
123 assert!(validator.validate(&invalid_value).is_err());
124 }
125
126 #[test]
127 fn test_max_strlen_validator_non_text() {
128 let validator = MaxStrlenValidator(5);
129 let non_text_value = Value::Uint32(crate::prelude::Uint32(42));
130 assert!(validator.validate(&non_text_value).is_err());
131 }
132
133 #[test]
134 fn test_min_strlen_validator() {
135 let validator = MinStrlenValidator(5);
136 let valid_value = Value::Text(Text("Hello".to_string()));
137 let invalid_value = Value::Text(Text("Hi".to_string()));
138 assert!(validator.validate(&valid_value).is_ok());
139 assert!(validator.validate(&invalid_value).is_err());
140 }
141
142 #[test]
143 fn test_min_strlen_validator_non_text() {
144 let validator = MinStrlenValidator(5);
145 let non_text_value = Value::Uint32(crate::prelude::Uint32(42));
146 assert!(validator.validate(&non_text_value).is_err());
147 }
148
149 #[test]
150 fn test_range_strlen_validator() {
151 let validator = RangeStrlenValidator(3, 10);
152 let valid_value = Value::Text(Text("Hello".to_string()));
153 let too_short_value = Value::Text(Text("Hi".to_string()));
154 let too_long_value = Value::Text(Text("Hello, World!".to_string()));
155 assert!(validator.validate(&valid_value).is_ok());
156 assert!(validator.validate(&too_short_value).is_err());
157 assert!(validator.validate(&too_long_value).is_err());
158 }
159
160 #[test]
161 fn test_range_strlen_validator_non_text() {
162 let validator = RangeStrlenValidator(3, 10);
163 let non_text_value = Value::Uint32(crate::prelude::Uint32(42));
164 assert!(validator.validate(&non_text_value).is_err());
165 }
166
167 #[test]
168 fn test_strlen_validators_count_unicode_characters() {
169 let emoji = Value::Text(Text("🙂".to_string()));
170 let accented = Value::Text(Text("héllo".to_string()));
171
172 assert!(MaxStrlenValidator(1).validate(&emoji).is_ok());
173 assert!(MaxStrlenValidator(5).validate(&accented).is_ok());
174 assert!(MinStrlenValidator(2).validate(&emoji).is_err());
175 assert!(MinStrlenValidator(6).validate(&accented).is_err());
176 assert!(RangeStrlenValidator(1, 1).validate(&emoji).is_ok());
177 assert!(RangeStrlenValidator(2, 4).validate(&emoji).is_err());
178 assert!(RangeStrlenValidator(5, 5).validate(&accented).is_ok());
179 }
180
181 #[test]
182 fn test_strlen_validator_error_reports_character_count() {
183 let two_emoji = Value::Text(Text("🙂🙂".to_string()));
184
185 let err = MaxStrlenValidator(1).validate(&two_emoji).unwrap_err();
186
187 assert!(err.to_string().contains("String length 2 exceeds"), "{err}");
188 }
189}