libgir/config/
ident.rs

1use std::fmt;
2
3use log::error;
4use regex::Regex;
5use toml::Value;
6
7use super::error::TomlHelper;
8
9#[derive(Clone, Debug)]
10pub enum Ident {
11    Name(String),
12    Pattern(Box<Regex>),
13}
14
15impl fmt::Display for Ident {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        match self {
18            Self::Name(name) => f.write_str(name),
19            Self::Pattern(regex) => write!(f, "Regex {regex}"),
20        }
21    }
22}
23
24impl PartialEq for Ident {
25    fn eq(&self, other: &Ident) -> bool {
26        match (self, other) {
27            (Self::Name(s1), Self::Name(s2)) => s1 == s2,
28            (Self::Pattern(r1), Self::Pattern(r2)) => r1.as_str() == r2.as_str(),
29            _ => false,
30        }
31    }
32}
33
34impl Eq for Ident {}
35
36impl Ident {
37    pub fn parse(toml: &Value, object_name: &str, what: &str) -> Option<Self> {
38        match toml.lookup("pattern").and_then(Value::as_str) {
39            Some(s) => Regex::new(&format!("^{s}$"))
40                .map(Box::new)
41                .map(Self::Pattern)
42                .map_err(|e| {
43                    error!(
44                        "Bad pattern `{}` in {} for `{}`: {}",
45                        s, what, object_name, e
46                    );
47                    e
48                })
49                .ok(),
50            None => match toml.lookup("name").and_then(Value::as_str) {
51                Some(name) => {
52                    if name.contains(['.', '+', '*'].as_ref()) {
53                        error!(
54                            "Should be `pattern` instead of `name` in {} for `{}`",
55                            what, object_name
56                        );
57                        None
58                    } else {
59                        Some(Self::Name(name.into()))
60                    }
61                }
62                None => None,
63            },
64        }
65    }
66
67    pub fn is_match(&self, name: &str) -> bool {
68        use self::Ident::*;
69        match self {
70            Name(n) => name == n,
71            Pattern(regex) => regex.is_match(name),
72        }
73    }
74}