error_handling/
error_handling.rs

1//! Advanced example showing error handling with ValidationError
2
3use validator_rs::{ValidationError, ValidationResult};
4use validator_rs::*;
5use validator_rs::url::is_valid_https_url;
6
7/// Example struct for user registration
8#[derive(Debug)]
9struct UserRegistration {
10    email: String,
11    phone: String,
12    website: String,
13    credit_card: String,
14}
15
16impl UserRegistration {
17    /// Validates all fields and returns a list of errors
18    fn validate(&self) -> Result<(), Vec<ValidationError>> {
19        let mut errors = Vec::new();
20
21        // Validate email
22        if !is_valid_email(&self.email) {
23            errors.push(ValidationError::new("email", "Invalid email format"));
24        }
25
26        // Validate phone
27        if !is_valid_phone(&self.phone) {
28            errors.push(ValidationError::new("phone", "Invalid phone number"));
29        }
30
31        // Validate website
32        if !is_valid_https_url(&self.website) {
33            errors.push(ValidationError::new("website", "Must be a valid HTTPS URL"));
34        }
35
36        // Validate credit card
37        if !credit_card::is_valid_credit_card(&self.credit_card) {
38            errors.push(ValidationError::new("credit_card", "Invalid credit card number"));
39        }
40
41        if errors.is_empty() {
42            Ok(())
43        } else {
44            Err(errors)
45        }
46    }
47}
48
49/// Validates a password with multiple rules
50fn validate_password(password: &str) -> Result<(), Vec<String>> {
51    let mut errors = Vec::new();
52
53    if !string::has_min_length(password, 8) {
54        errors.push("Password must be at least 8 characters long".to_string());
55    }
56
57    if !string::has_max_length(password, 128) {
58        errors.push("Password must not exceed 128 characters".to_string());
59    }
60
61    if !password.chars().any(|c| c.is_uppercase()) {
62        errors.push("Password must contain at least one uppercase letter".to_string());
63    }
64
65    if !password.chars().any(|c| c.is_lowercase()) {
66        errors.push("Password must contain at least one lowercase letter".to_string());
67    }
68
69    if !password.chars().any(|c| c.is_ascii_digit()) {
70        errors.push("Password must contain at least one digit".to_string());
71    }
72
73    if !password.chars().any(|c| !c.is_alphanumeric()) {
74        errors.push("Password must contain at least one special character".to_string());
75    }
76
77    if errors.is_empty() {
78        Ok(())
79    } else {
80        Err(errors)
81    }
82}
83
84/// Validates age with range checking
85fn validate_age(age: i32) -> ValidationResult {
86    if !numeric::is_in_range(age, 18, 120) {
87        return Err(ValidationError::new("age", "Age must be between 18 and 120"));
88    }
89    Ok(())
90}
91
92fn main() {
93    println!("=== Advanced Validation Examples ===\n");
94
95    // Example 1: Valid user registration
96    println!("--- Valid User Registration ---");
97    let valid_user = UserRegistration {
98        email: "user@example.com".to_string(),
99        phone: "+12345678901".to_string(),
100        website: "https://example.com".to_string(),
101        credit_card: "4532015112830366".to_string(),
102    };
103
104    match valid_user.validate() {
105        Ok(()) => println!("✓ User registration is valid!"),
106        Err(errors) => {
107            println!("✗ Validation errors:");
108            for error in errors {
109                println!("  - {}", error);
110            }
111        }
112    }
113    println!();
114
115    // Example 2: Invalid user registration
116    println!("--- Invalid User Registration ---");
117    let invalid_user = UserRegistration {
118        email: "invalid-email".to_string(),
119        phone: "123".to_string(),
120        website: "http://example.com".to_string(), // HTTP not HTTPS
121        credit_card: "1234567890123456".to_string(),
122    };
123
124    match invalid_user.validate() {
125        Ok(()) => println!("✓ User registration is valid!"),
126        Err(errors) => {
127            println!("✗ Validation errors:");
128            for error in errors {
129                println!("  - {}", error);
130            }
131        }
132    }
133    println!();
134
135    // Example 3: Password validation
136    println!("--- Password Validation ---");
137    let passwords = vec![
138        ("weak", "password"),
139        ("better", "Password123!"),
140        ("short", "Pass1!"),
141    ];
142
143    for (label, password) in passwords {
144        print!("Password '{}' ({}): ", password, label);
145        match validate_password(password) {
146            Ok(()) => println!("✓ Valid"),
147            Err(errors) => {
148                println!("✗ Invalid");
149                for error in errors {
150                    println!("    - {}", error);
151                }
152            }
153        }
154    }
155    println!();
156
157    // Example 4: Age validation
158    println!("--- Age Validation ---");
159    let ages = vec![17, 25, 65, 121];
160    for age in ages {
161        print!("Age {}: ", age);
162        match validate_age(age) {
163            Ok(()) => println!("✓ Valid"),
164            Err(error) => println!("✗ {}", error),
165        }
166    }
167    println!();
168
169    println!("=== End of Advanced Examples ===");
170}
171