• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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