ddoc/config/
element_key.rs

1use {
2    crate::*,
3    std::{
4        fmt,
5        str::FromStr,
6    },
7};
8
9#[derive(Debug, Clone)]
10pub struct ElementKey {
11    pub etype: ElementType,
12    pub classes: Vec<String>,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16pub enum ElementType {
17    HtmlTag(String),
18    Menu,
19    Link,
20    Toc,
21    Main,
22}
23
24impl fmt::Display for ElementType {
25    fn fmt(
26        &self,
27        f: &mut fmt::Formatter,
28    ) -> fmt::Result {
29        match self {
30            ElementType::HtmlTag(tag) => write!(f, "{}", tag),
31            ElementType::Menu => write!(f, "ddoc-menu"),
32            ElementType::Link => write!(f, "ddoc-link"),
33            ElementType::Toc => write!(f, "ddoc-toc"),
34            ElementType::Main => write!(f, "ddoc-main"),
35        }
36    }
37}
38impl fmt::Display for ElementKey {
39    fn fmt(
40        &self,
41        f: &mut fmt::Formatter,
42    ) -> fmt::Result {
43        write!(f, "{}", &self.etype)?;
44        for class in &self.classes {
45            write!(f, ".{}", class)?;
46        }
47        Ok(())
48    }
49}
50
51impl FromStr for ElementKey {
52    type Err = DdError;
53
54    fn from_str(s: &str) -> Result<Self, Self::Err> {
55        // FIXME check validity of tag/class names
56        let parts: Vec<&str> = s.split('.').collect();
57        let etype = match parts[0] {
58            "ddoc-menu" => ElementType::Menu,
59            "ddoc-link" => ElementType::Link,
60            "ddoc-toc" => ElementType::Toc,
61            "ddoc-main" => ElementType::Main,
62            tag => ElementType::HtmlTag(tag.to_string()),
63        };
64        let classes = parts[1..].iter().map(|s| s.to_string()).collect();
65        Ok(ElementKey { etype, classes })
66    }
67}
68
69impl<'de> serde::Deserialize<'de> for ElementKey {
70    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
71        let s = String::deserialize(deserializer)?;
72        s.parse().map_err(serde::de::Error::custom)
73    }
74}