rust_ocpp/v2_0_1/helpers/
validator.rs

1use std::sync::OnceLock;
2
3use regex::Regex;
4use validator::ValidationError;
5
6static REGEX: OnceLock<Regex> = OnceLock::new();
7
8/// Helper function to validate identifierString
9///
10/// # identfierString
11/// This is a case-insensitive dataType and can only contain characters from the following
12/// character set: `a-z`, `A-Z`, `0-9`, `'*'`, `'-'`, `'_'`, `'='`, `':'`, `'+'`, `'|'`, `'@'`, `'.'`
13pub fn validate_identifier_string(s: &str) -> Result<(), ValidationError> {
14    // regex for identifierString as defined by the specification
15    let res = REGEX
16        .get_or_init(|| Regex::new(r"^[a-zA-Z0-9*+=:|@._-]*$").unwrap())
17        .is_match(s);
18
19    match res {
20        true => Ok(()),
21        false => Err(ValidationError::new("Not a valid identifierString")),
22    }
23}
24
25#[cfg(test)]
26mod test {
27    use super::validate_identifier_string;
28
29    #[test]
30    fn good_case() {
31        let good_cases = ["abc123", "A*C_|..", "||||", "ABCabc123:==@"];
32
33        for case in good_cases.iter() {
34            dbg!(case);
35            validate_identifier_string(case).unwrap();
36        }
37    }
38
39    #[test]
40    fn bad_case() {
41        let bad_cases = [
42            "abc123/",
43            "https://",
44            "ABC#123",
45            ",,,,",
46            "Test test",
47            "123 Prøve",
48            "123 Test?",
49        ];
50
51        for case in bad_cases.iter() {
52            dbg!(case);
53            validate_identifier_string(case).unwrap_err();
54        }
55    }
56}