use std::{
env,
fs::{self, DirEntry, File},
io::{self, Write},
path::{Path, PathBuf},
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_dir = env::var("OUT_DIR").unwrap();
compile(
PathBuf::from("scss/index.scss"),
PathBuf::from(out_dir).join("styles.css"),
)?;
let here = Path::new(".").canonicalize()?;
visit_dirs(&here, &handle_dir)?;
Ok(())
}
fn handle_dir(e: &DirEntry) -> Result<(), Box<dyn std::error::Error>> {
let path = e.path();
if path.extension().is_some() && path.extension().unwrap().eq("scss") {
let mut output = path.clone();
output.set_extension("css");
compile(path, output)?;
}
Ok(())
}
fn compile(input: PathBuf, output: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
if PathBuf::from("scss/index.scss").canonicalize()?.eq(&input) {
return Ok(());
}
let out_dir = env::var("OUT_DIR").unwrap();
let output = PathBuf::from(out_dir).join(output.file_name().unwrap());
let mut output = File::create(output)?;
let opts = grass::Options::default();
let opts = opts.style(grass::OutputStyle::Compressed);
let css_text = grass::from_path(input, &opts).unwrap_or_else(|e| {
panic!("Sass Error: {e:#?}");
});
output.write_all(css_text.as_bytes())?;
Ok(())
}
#[allow(clippy::type_complexity)]
fn visit_dirs(
dir: &Path,
cb: &dyn Fn(&DirEntry) -> Result<(), Box<dyn std::error::Error>>,
) -> io::Result<()> {
let ignore = |pattern: &str| -> bool { dir.file_name().unwrap().eq(pattern) };
if dir.is_dir() && !ignore(".git") && !ignore("target") && !ignore("scss") {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
visit_dirs(&path, cb)?;
} else {
cb(&entry).unwrap();
}
}
}
Ok(())
}