aboutsummaryrefslogtreecommitdiffstats
path: root/validator/src/length.rs
diff options
context:
space:
mode:
Diffstat (limited to 'validator/src/length.rs')
-rw-r--r--validator/src/length.rs94
1 files changed, 94 insertions, 0 deletions
diff --git a/validator/src/length.rs b/validator/src/length.rs
new file mode 100644
index 0000000..358317f
--- /dev/null
+++ b/validator/src/length.rs
@@ -0,0 +1,94 @@
+use types::Validator;
+
+// a bit sad but we can generically refer to a struct that has a len() method
+// so we impl our own trait for it
+pub trait HasLen {
+ fn length(&self) -> u64;
+}
+
+impl<'a> HasLen for &'a String {
+ fn length(&self) -> u64 {
+ self.len() as u64
+ }
+}
+
+impl<'a> HasLen for &'a str {
+ fn length(&self) -> u64 {
+ self.len() as u64
+ }
+}
+
+impl<T> HasLen for Vec<T> {
+ fn length(&self) -> u64 {
+ self.len() as u64
+ }
+}
+impl<'a, T> HasLen for &'a Vec<T> {
+ fn length(&self) -> u64 {
+ self.len() as u64
+ }
+}
+
+/// Validates the length of the value given.
+/// If the validator has `equal` set, it will ignore any `min` and `max` value.
+///
+/// If you apply it on String, don't forget that the length can be different
+/// from the number of visual characters for Unicode
+pub fn validate_length<T: HasLen>(length: Validator, val: T) -> bool {
+ match length {
+ Validator::Length { min, max, equal } => {
+ let val_length = val.length();
+ if let Some(eq) = equal {
+ return val_length == eq;
+ }
+ if let Some(m) = min {
+ if val_length < m {
+ return false;
+ }
+ }
+ if let Some(m) = max {
+ if val_length > m {
+ return false;
+ }
+ }
+ },
+ _ => unreachable!()
+ }
+
+ true
+}
+
+#[cfg(test)]
+mod tests {
+ use super::{validate_length, Validator};
+
+ #[test]
+ fn test_validate_length_equal_overrides_min_max() {
+ let validator = Validator::Length { min: Some(1), max: Some(2), equal: Some(5) };
+ assert_eq!(validate_length(validator, "hello"), true);
+ }
+
+ #[test]
+ fn test_validate_length_string_min_max() {
+ let validator = Validator::Length { min: Some(1), max: Some(10), equal: None };
+ assert_eq!(validate_length(validator, "hello"), true);
+ }
+
+ #[test]
+ fn test_validate_length_string_min_only() {
+ let validator = Validator::Length { min: Some(10), max: None, equal: None };
+ assert_eq!(validate_length(validator, "hello"), false);
+ }
+
+ #[test]
+ fn test_validate_length_string_max_only() {
+ let validator = Validator::Length { min: None, max: Some(1), equal: None };
+ assert_eq!(validate_length(validator, "hello"), false);
+ }
+
+ #[test]
+ fn test_validate_length_vec() {
+ let validator = Validator::Length { min: None, max: None, equal: Some(3) };
+ assert_eq!(validate_length(validator, vec![1, 2, 3]), true);
+ }
+}