pest_css_parser/stylesheet/
rule.rs1use std::collections::HashMap;
2
3use super::constants::COLORS;
4
5pub type Specificity = (usize, usize, usize);
6
7#[derive(Debug, Clone, PartialEq)]
8pub enum CssRule {
9 Normal(NormalRule),
10 Comment(String),
11}
12
13#[derive(Debug, Default, Clone, PartialEq)]
14pub struct NormalRule {
15 pub selectors: Vec<Selector>,
16 pub declarations: HashMap<String, Value>,
17}
18
19#[derive(Debug, Clone, PartialEq)]
20pub enum Selector {
21 Simple(SimpleSelector),
22}
23
24#[derive(Debug, Clone, Default, PartialEq)]
25pub struct SimpleSelector {
26 pub id: Option<String>,
27 pub class: Vec<String>,
28 pub tag_name: Option<String>,
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub enum Value {
33 Keyword(String),
34 Length(f32, Unit),
35 Color(Color),
36 StringLiteral(String),
37}
38
39#[derive(Debug, Copy, Clone, PartialEq)]
40pub enum Unit {
41 Cm,
43 Mm,
45 In,
47 Px,
49 Pt,
51 Pc,
53 Em,
55 Ex,
57 Ch,
59 Rem,
61 Vw,
63 Vh,
65 VMin,
67 VMax,
69 Percent,
71}
72
73#[derive(Debug, Default, Clone, Copy, PartialEq)]
74pub struct Color {
75 pub r: u8,
76 pub g: u8,
77 pub b: u8,
78 pub a: u8,
79}
80
81impl Selector {
82 pub fn specificity(&self) -> Option<Specificity> {
89 match self {
90 Selector::Simple(simple) => {
91 let a = simple.id.iter().count();
92 let b = simple.class.len();
93 let c = simple.tag_name.iter().count();
94 Some((a, b, c))
95 }
96 }
97 }
98}
99
100impl From<&str> for Unit {
101 fn from(value: &str) -> Self {
102 match value {
103 "cm" => Unit::Cm,
104 "mm" => Unit::Mm,
105 "in" => Unit::In,
106 "px" => Unit::Px,
107 "pt" => Unit::Pt,
108 "pc" => Unit::Pc,
109
110 "em" => Unit::Em,
111 "ex" => Unit::Ex,
112 "ch" => Unit::Ch,
113 "rem" => Unit::Rem,
114 "vw" => Unit::Vw,
115 "vh" => Unit::Vh,
116 "vmin" => Unit::VMin,
117 "vmax" => Unit::VMax,
118 "%" => Unit::Percent,
119 _ => Unit::Px,
120 }
121 }
122}
123
124impl Value {
125 pub fn to_px(&self) -> f32 {
127 match *self {
128 Value::Length(f, _) => f,
129 _ => 0.0,
130 }
131 }
132}
133
134impl Color {
135 pub fn from_hex(hex: &str) -> Self {
136 let hex = hex.trim_start_matches('#');
137 let num = i32::from_str_radix(&hex[0..], 16).unwrap();
138 let r = (num >> 16) as u8;
139 let g = (num >> 8) as u8;
140 let b = num as u8;
141
142 Self {
143 r,
144 g,
145 b,
146 a: 255
147 }
148 }
149
150 pub fn from_keyword(name: &str) -> Self {
151 let unlocked = COLORS.lock().unwrap();
152 *unlocked.get(&name.to_lowercase()).unwrap()
153 }
154}