1 /// Trait for validating item (for ex. validate X.509 structure) 2 /// 3 /// # Examples 4 /// 5 /// Using callbacks: 6 /// 7 /// ``` 8 /// use x509_parser::certificate::X509Certificate; 9 /// use x509_parser::validate::Validate; 10 /// 11 /// #[cfg(feature = "validate")] 12 /// fn validate_certificate(x509: &X509Certificate<'_>) -> Result<(), &'static str> { 13 /// println!(" Subject: {}", x509.subject()); 14 /// // validate and print warnings and errors to stderr 15 /// let ok = x509.validate( 16 /// |msg| { 17 /// eprintln!(" [W] {}", msg); 18 /// }, 19 /// |msg| { 20 /// eprintln!(" [E] {}", msg); 21 /// }, 22 /// ); 23 /// print!("Structure validation status: "); 24 /// if ok { 25 /// println!("Ok"); 26 /// Ok(()) 27 /// } else { 28 /// println!("FAIL"); 29 /// Err("validation failed") 30 /// } 31 /// } 32 /// ``` 33 /// 34 /// Collecting warnings and errors to `Vec`: 35 /// 36 /// ``` 37 /// use x509_parser::certificate::X509Certificate; 38 /// use x509_parser::validate::Validate; 39 /// 40 /// #[cfg(feature = "validate")] 41 /// fn validate_certificate(x509: &X509Certificate<'_>) -> Result<(), &'static str> { 42 /// println!(" Subject: {}", x509.subject()); 43 /// // validate and print warnings and errors to stderr 44 /// let (ok, warnings, errors) = x509.validate_to_vec(); 45 /// print!("Structure validation status: "); 46 /// if ok { 47 /// println!("Ok"); 48 /// } else { 49 /// println!("FAIL"); 50 /// } 51 /// for warning in &warnings { 52 /// eprintln!(" [W] {}", warning); 53 /// } 54 /// for error in &errors { 55 /// eprintln!(" [E] {}", error); 56 /// } 57 /// println!(); 58 /// if !errors.is_empty() { 59 /// return Err("validation failed"); 60 /// } 61 /// Ok(()) 62 /// } 63 /// ``` 64 pub trait Validate { 65 /// Attempts to validate current item. 66 /// 67 /// Returns `true` if item was validated. 68 /// 69 /// Call `warn()` if a non-fatal error was encountered, and `err()` 70 /// if the error is fatal. These fucntions receive a description of the error. validate<W, E>(&self, warn: W, err: E) -> bool where W: FnMut(&str), E: FnMut(&str)71 fn validate<W, E>(&self, warn: W, err: E) -> bool 72 where 73 W: FnMut(&str), 74 E: FnMut(&str); 75 76 /// Attempts to validate current item, storing warning and errors in `Vec`. 77 /// 78 /// Returns the validation result (`true` if validated), the list of warnings, 79 /// and the list of errors. validate_to_vec(&self) -> (bool, Vec<String>, Vec<String>)80 fn validate_to_vec(&self) -> (bool, Vec<String>, Vec<String>) { 81 let mut warn_list = Vec::new(); 82 let mut err_list = Vec::new(); 83 let res = self.validate( 84 |s| warn_list.push(s.to_owned()), 85 |s| err_list.push(s.to_owned()), 86 ); 87 (res, warn_list, err_list) 88 } 89 } 90 91 #[cfg(test)] 92 mod tests { 93 use super::Validate; 94 95 struct V1 { 96 a: u32, 97 } 98 99 impl Validate for V1 { validate<W, E>(&self, mut warn: W, _err: E) -> bool where W: FnMut(&str), E: FnMut(&str),100 fn validate<W, E>(&self, mut warn: W, _err: E) -> bool 101 where 102 W: FnMut(&str), 103 E: FnMut(&str), 104 { 105 if self.a > 10 { 106 warn("a is greater than 10"); 107 } 108 true 109 } 110 } 111 112 #[test] validate_warn()113 fn validate_warn() { 114 let v1 = V1 { a: 1 }; 115 let (res, warn, err) = v1.validate_to_vec(); 116 assert!(res); 117 assert!(warn.is_empty()); 118 assert!(err.is_empty()); 119 // same, with one warning 120 let v20 = V1 { a: 20 }; 121 let (res, warn, err) = v20.validate_to_vec(); 122 assert!(res); 123 assert_eq!(warn, vec!["a is greater than 10".to_string()]); 124 assert!(err.is_empty()); 125 } 126 } 127