1use crate::utils::packaging::{minify_asset, Asset};
22use rumtk_core::hash::has_same_hash;
23use rumtk_core::strings::{RUMString, RUMStringConversions};
24use std::{fs, path};
25
26mod animations;
27mod basic;
28mod components;
29mod default;
30mod fonts;
31mod forms;
32mod gap;
33mod imgs;
34mod index;
35mod layout;
36mod theme;
37
38pub const DEFAULT_OUT_CSS_DIR: &str = "./static/css";
39pub const DEFAULT_OUT_CSS: &str = "bundle.min.css";
40
41pub fn bundle_css(sources: &Vec<String>, out_dir: &str, out_file: &str, skip_default_css: bool) {
42 let mut css: RUMString = RUMString::default();
43
44 if !skip_default_css {
45 css += theme::THEME;
46 css += index::BODY;
47 css += basic::BASIC_CSS;
48 css += default::DEFAULT_CSS;
49 css += fonts::FONTS_CSS;
50 css += gap::GAP_CSS;
51 css += animations::ANIMATIONS_CSS;
52 css += forms::FORM_CSS;
53 css += components::LIST_CSS;
54 css += layout::LAYOUT_CSS;
55 css += imgs::IMGS;
56 }
57
58 for source in sources {
59 let css_data = fs::read_to_string(source).unwrap_or_default();
60 css += &css_data;
61 }
62
63 fs::create_dir_all(out_dir).unwrap_or_default();
64
65 let out_path = path::Path::new(out_dir)
66 .join(out_file)
67 .with_extension("css")
68 .to_str()
69 .expect("Could not create path to CSS file!")
70 .to_string();
71
72 let minified = minify_asset(Asset::CSS(&css))
73 .expect("Failed to minify the CSS contents!")
74 .to_rumstring();
75
76 let file_exists = fs::exists(&out_path).unwrap_or_default();
77 let skip_write_css = file_exists
78 && has_same_hash(
79 &minified,
80 &fs::read_to_string(&out_path)
81 .unwrap_or_default()
82 .to_rumstring(),
83 );
84
85 if !skip_write_css {
86 println!("Generated minified CSS file!");
87 fs::write(&out_path, minified).expect("Failed to write to CSS file!");
88 }
89}
90
91pub fn collect_css_sources(root: &str, depth: u8) -> Vec<String> {
92 let mut files = Vec::<String>::new();
93
94 let dirs = match fs::read_dir(root) {
95 Ok(dirs) => dirs,
96 Err(_) => return files,
97 };
98
99 for dir_entry in dirs {
100 let dir = dir_entry.unwrap();
101 let dir_name = dir.file_name().into_string().unwrap();
102 let dir_path = dir.path().to_str().unwrap().to_string();
103 if dir_name.ends_with(".css") && dir_name != DEFAULT_OUT_CSS {
104 files.push(dir_path.clone());
105 }
106
107 if depth == 255 {
108 return files;
109 }
110
111 if dir.file_type().unwrap().is_dir() {
112 files.extend(collect_css_sources(&dir_path, depth + 1));
113 }
114 }
115
116 files
117}
118
119#[macro_export]
120macro_rules! rumtk_web_compile_css_bundle {
121 ( ) => {{
122 use $crate::css::DEFAULT_OUT_CSS_DIR;
123 let sources = collect_css_sources(DEFAULT_OUT_CSS_DIR, 0);
124 rumtk_web_compile_css_bundle!(DEFAULT_OUT_CSS_DIR, true);
125 }};
126 ( $static_dir_path:expr ) => {{
127 rumtk_web_compile_css_bundle!($static_dir_path, true);
128 }};
129 ( $static_dir_path:expr, $skip_default_css:expr ) => {{
130 use $crate::css::{bundle_css, collect_css_sources};
131 use $crate::css::{DEFAULT_OUT_CSS, DEFAULT_OUT_CSS_DIR};
132 let sources = collect_css_sources($static_dir_path, 0);
133 bundle_css(
134 &sources,
135 DEFAULT_OUT_CSS_DIR,
136 DEFAULT_OUT_CSS,
137 $skip_default_css,
138 );
139 }};
140}