ddoc/config/
element_key.rs1use {
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 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}