gen_parser/ast/
style.rs

1use std::{collections::HashMap, fmt::Display};
2
3use gen_utils::common::tokenizer::{FUNCTION_SIGN, HOLDER_END, HOLDER_START, IMPORT, STYLE_CLASS, STYLE_ID, STYLE_PESUDO};
4
5use super::{props_to_style_string, ASTNodes, Props};
6
7#[derive(Debug, Clone, PartialEq, Hash, Eq)]
8pub enum StyleType {
9    // class: `.`
10    Class,
11    // id: `#`
12    Id,
13    // Pseudo: `::`
14    Pseudo,
15    // Import: `import`
16    Import,
17    // Identifier: `@`
18    Identifier,
19}
20
21impl Default for StyleType {
22    fn default() -> Self {
23        Self::Class
24    }
25}
26
27#[allow(dead_code)]
28impl StyleType {
29    pub fn is_class(&self) -> bool {
30        matches!(self, Self::Class)
31    }
32    pub fn is_id(&self) -> bool {
33        matches!(self, Self::Id)
34    }
35    pub fn is_pseudo(&self) -> bool {
36        matches!(self, Self::Pseudo)
37    }
38}
39
40impl From<&str> for StyleType {
41    fn from(value: &str) -> Self {
42        match value {
43            STYLE_CLASS => StyleType::Class,
44            STYLE_ID => StyleType::Id,
45            STYLE_PESUDO => StyleType::Pseudo,
46            IMPORT => StyleType::Import,
47            FUNCTION_SIGN => StyleType::Identifier,
48            _ => panic!("Invalid style"),
49        }
50    }
51}
52
53impl Display for StyleType {
54    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
55        let res = match self {
56            StyleType::Class => STYLE_CLASS,
57            StyleType::Id => STYLE_ID,
58            StyleType::Pseudo => STYLE_PESUDO,
59            StyleType::Import => IMPORT,
60            StyleType::Identifier => FUNCTION_SIGN,
61        };
62        f.write_str(res)
63    }
64}
65
66/// # Style for ASTNodes
67#[derive(Debug, Clone, PartialEq)]
68pub struct Style {
69    name: String,
70    ty: StyleType,
71    props: Props,
72    children: Option<Vec<ASTNodes>>,
73    parent: Option<ASTNodes>,
74}
75
76#[allow(dead_code)]
77impl Style {
78    pub fn new(
79        name: &str,
80        props: Props,
81        ty: StyleType,
82        children: Option<Vec<ASTNodes>>,
83        parent: Option<ASTNodes>,
84    ) -> Self {
85        Style {
86            name: name.to_string(),
87            ty,
88            props,
89            children,
90            parent,
91        }
92    }
93    pub fn new_style_start(name: &str, ty: StyleType) -> Self {
94        Style {
95            name: name.to_string(),
96            ty,
97            props: None,
98            children: None,
99            parent: None,
100        }
101    }
102    pub fn set_name(&mut self, name: &str) {
103        self.name = name.to_string();
104    }
105    pub fn set_ty(&mut self, ty: StyleType) {
106        self.ty = ty;
107    }
108    pub fn set_props(&mut self, props: Props) {
109        self.props = props;
110    }
111    pub fn extend_props(&mut self, props: HashMap<super::PropsKey, crate::Value>) {
112        match self.props {
113            Some(ref mut p) => {
114                p.extend(props);
115            }
116            None => self.props = Some(props),
117        }
118    }
119    pub fn set_children(&mut self, children: Vec<ASTNodes>) {
120        match self.children {
121            Some(_) => {
122                let _ = self.children.replace(children);
123            }
124            None => self.children = Some(children),
125        }
126    }
127    pub fn set_parent(&mut self, parent: ASTNodes) {
128        match self.parent {
129            Some(_) => {
130                let _ = self.parent.replace(parent);
131            }
132            None => self.parent = Some(parent),
133        }
134    }
135    pub fn get_name(&self) -> &str {
136        &self.name
137    }
138    pub fn get_type(&self) -> StyleType {
139        self.ty.clone()
140    }
141    pub fn has_children(&self) -> bool {
142        self.children.is_some()
143    }
144    pub fn get_children(&self) -> Option<&Vec<ASTNodes>> {
145        self.children.as_ref()
146    }
147    pub fn has_props(&self) -> bool {
148        self.props.is_some()
149    }
150    pub fn get_props(&self) -> Option<&HashMap<crate::PropsKey, crate::Value>> {
151        self.props.as_ref()
152    }
153    pub fn get_parent(&self) -> Option<&ASTNodes> {
154        self.parent.as_ref()
155    }
156    pub fn has_parent(&self) -> bool {
157        self.parent.is_some()
158    }
159}
160
161impl Display for Style {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        // name and type
164        let _ = f.write_fmt(format_args!(
165            "{}{}{}",
166            self.get_type().to_string(),
167            self.get_name(),
168            HOLDER_START
169        ));
170
171        // properties
172        let props_str = props_to_style_string(self.props.clone());
173        if !props_str.is_empty() {
174            let _ = f.write_fmt(format_args!("{}", props_str));
175        }
176        // children
177
178        if self.has_children() {
179            let _ = f.write_fmt(format_args!(
180                "\n{}",
181                self.children
182                    .as_ref()
183                    .unwrap()
184                    .into_iter()
185                    .map(|item| item.to_string())
186                    .collect::<Vec<String>>()
187                    .join("\n")
188            ));
189            let _ = f.write_str("\n");
190        }
191        f.write_str(HOLDER_END)
192    }
193}