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