1pub mod builder;
2pub mod dev;
3pub mod classes;
4pub mod reset;
5pub mod components;
6pub mod config;
7pub mod harmonic;
8pub mod media_query;
9pub mod parser;
10pub mod utilities;
11
12use builder::LayoutElement;
13use config::LayoutStyleConfig;
14use indoc::formatdoc;
15use media_query::MediaQuery;
16use std::collections::{HashMap, HashSet};
17
18pub fn generate_final_css(
19 css_set: &HashSet<String>,
20 mq_rules: &HashMap<MediaQuery, HashSet<String>>,
21) -> String {
22 let mut final_css = css_set.iter().cloned().collect::<Vec<String>>().join("");
24
25 let mut ordered_mq_keys: Vec<MediaQuery> = mq_rules.keys().cloned().collect();
29
30 ordered_mq_keys.sort();
32
33 for key in ordered_mq_keys {
34 if let Some(hash_set) = mq_rules.get(&key) {
35 let rule_with_modified_selector: String = hash_set
38 .iter()
39 .map(|s| match &key {
40 MediaQuery::InferiorOrEqualTo(breakpoint) => {
41 s.replace("[layout", format!("[layout{breakpoint}px").as_str())
42 }
43 MediaQuery::SuperiorTo(breakpoint, attribute_value) => s.replace(
44 "-l[layout",
45 format!("-l[layout{breakpoint}px=\"{attribute_value}\"][layout")
46 .as_str(),
47 ),
48 })
49 .collect::<Vec<String>>()
50 .join("");
51 let wrapped_in_mq = match key {
54 MediaQuery::SuperiorTo(breakpoint, _) => formatdoc!(
55 r#"
56 @media (width > {breakpoint}px) {{
57 {rule_with_modified_selector}
58 }}
59 "#
60 ),
61 MediaQuery::InferiorOrEqualTo(breakpoint) => formatdoc!(
62 r#"
63 @media (width <= {breakpoint}px) {{
64 {rule_with_modified_selector}
65 }}"#
66 ),
67 };
68 final_css.push_str(wrapped_in_mq.as_str());
70 }
71 }
72 final_css
73}
74
75pub fn get_css_from_string<'a>(
79 text: &'a String,
80 previous_css_rules: Option<&mut HashSet<String>>,
81 previous_css_mq_rules: Option<&mut HashMap<MediaQuery, HashSet<String>>>,
82 layout_style_config: &LayoutStyleConfig,
83) -> String {
84 let mut layout_elements: HashSet<LayoutElement> = HashSet::new();
85
86 let mut local_css_rules: HashSet<String> = HashSet::new();
87 let css_rules = match previous_css_rules {
88 Some(x) => x,
89 None => &mut local_css_rules,
90 };
91
92 css_rules.insert(reset::reset_css(&layout_style_config));
93 if layout_style_config.dev {
94 css_rules.insert(dev::DEV_CSS.to_string());
95 }
96
97 let mut local_css_mq_rules: HashMap<MediaQuery, HashSet<String>> = HashMap::new();
98 let css_mq_rules = match previous_css_mq_rules {
99 Some(x) => x,
100 None => &mut local_css_mq_rules,
101 };
102 let mut parser = parser::Parser::new(text);
103 parser.parse(&mut layout_elements);
104 for element in layout_elements.drain() {
105 element.insert_css(layout_style_config.harmonic_ratio, css_rules, css_mq_rules);
106 }
107 generate_final_css(&css_rules, &css_mq_rules)
108}