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