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