1mod parser;
8pub mod computed;
9pub mod css_modules;
10pub mod web_api;
11
12pub use parser::*;
13pub use computed::*;
14pub use css_modules::*;
15pub use web_api::*;
16
17use std::collections::HashMap;
18
19#[derive(Debug, Clone, PartialEq)]
21pub struct Declaration {
22 pub property: String,
23 pub value: String,
24}
25
26#[derive(Debug, Clone)]
28pub struct CssRule {
29 pub selectors: Vec<String>,
30 pub declarations: Vec<Declaration>,
31}
32
33#[derive(Debug, Clone, Default)]
35pub struct StyleSheet {
36 pub rules: Vec<CssRule>,
37}
38
39impl StyleSheet {
40 pub fn parse(css: &str) -> Result<Self, String> {
42 parser::parse_css(css)
43 }
44
45 pub fn declarations_for_class(&self, class: &str) -> Vec<Declaration> {
47 let mut result = Vec::new();
48 let class_selector = format!(".{}", class);
49 for rule in &self.rules {
50 if rule.selectors.iter().any(|s| s == &class_selector || s.contains(&class_selector)) {
51 result.extend(rule.declarations.clone());
52 }
53 }
54 result
55 }
56
57 pub fn declarations_for_tag(&self, tag: &str) -> Vec<Declaration> {
59 let mut result = Vec::new();
60 for rule in &self.rules {
61 if rule.selectors.iter().any(|s| s == tag) {
62 result.extend(rule.declarations.clone());
63 }
64 }
65 result
66 }
67
68 pub fn compute(&self, classes: &[String], tag: &str) -> HashMap<String, String> {
70 let mut map = HashMap::new();
71 for class in classes {
72 for decl in self.declarations_for_class(class) {
73 map.insert(decl.property, decl.value);
74 }
75 }
76 for decl in self.declarations_for_tag(tag) {
77 map.entry(decl.property).or_insert(decl.value);
78 }
79 map
80 }
81}