82 lines
2.2 KiB
Rust
82 lines
2.2 KiB
Rust
use std::env;
|
|
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::io::{self, BufRead};
|
|
use std::path::Path;
|
|
use std::path::PathBuf;
|
|
|
|
use regex::Regex;
|
|
|
|
fn main() {
|
|
// Tell Cargo to rerun this build script if any SCSS file
|
|
// in the 'src' directory or its subdirectories changes.
|
|
println!("cargo:rerun-if-changed=src/**/*.scss");
|
|
|
|
let out_dir = env::var("OUT_DIR").unwrap();
|
|
|
|
let style_src_path = PathBuf::from("src/_base.scss");
|
|
let style_dst_path = Path::new(&out_dir).join("style_vars.rs");
|
|
|
|
export_color_variables(&style_src_path, &style_dst_path)
|
|
}
|
|
|
|
// From https://doc.rust-lang.org/rust-by-example/std_misc/file/read_lines.html
|
|
// The output is wrapped in a Result to allow matching on errors.
|
|
// Returns an Iterator to the Reader of the lines of the file.
|
|
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
|
where
|
|
P: AsRef<Path>,
|
|
{
|
|
let file = File::open(filename)?;
|
|
Ok(io::BufReader::new(file).lines())
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct CssColorVariable<'a> {
|
|
name: &'a str,
|
|
value: &'a str,
|
|
}
|
|
|
|
impl<'a> CssColorVariable<'a> {
|
|
pub fn to_rust(&self) -> String {
|
|
format!(
|
|
"const {name}: &str = \"{value}\";",
|
|
name = self.name.replace('-', "_").to_uppercase(),
|
|
value = self.value
|
|
)
|
|
}
|
|
}
|
|
|
|
fn export_color_variables(src_path: &PathBuf, dst_path: &PathBuf) {
|
|
let mut dst_file = File::create(dst_path).unwrap();
|
|
if let Err(err) = dst_file.write(b"#[allow(dead_code)]\nmod style {") {
|
|
println!("{}", err);
|
|
return;
|
|
};
|
|
|
|
let re = Regex::new(r"^\$([^:]+):[[:space:]]*#([^$]+);[[:space:]]*$").unwrap();
|
|
|
|
if let Ok(lines) = read_lines(src_path) {
|
|
for line in lines.map_while(Result::ok) {
|
|
let Some(groups) = re.captures(&line) else {
|
|
continue;
|
|
};
|
|
|
|
let var = CssColorVariable {
|
|
name: &groups[1],
|
|
value: &groups[2],
|
|
};
|
|
|
|
let rust_export = var.to_rust();
|
|
if let Err(err) = dst_file.write_fmt(format_args!(" pub {}\n", rust_export)) {
|
|
println!("{}", err);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if let Err(err) = dst_file.write(b"}\n") {
|
|
println!("{}", err);
|
|
};
|
|
}
|