🔨 Make the Design System color tokens reachable from the rust code

The design system tokens are specified in the _base.scss file. To avoid to duplicate their value in a rust file, a new
step has been added to the building process to generate the `style_vars.rs` file which make the color tokens reachable
to the app.
This commit is contained in:
2024-03-10 11:40:00 +01:00
parent dd0754073c
commit 1073a592ed
2 changed files with 78 additions and 0 deletions

View File

@@ -31,3 +31,5 @@ futures = "0.3.29"
[build] [build]
target = "x86_64-unknown-linux-gnu" target = "x86_64-unknown-linux-gnu"
[build-dependencies]
regex = "1.10.3"

View File

@@ -1,5 +1,81 @@
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() { fn main() {
// Tell Cargo to rerun this build script if any SCSS file // Tell Cargo to rerun this build script if any SCSS file
// in the 'src' directory or its subdirectories changes. // in the 'src' directory or its subdirectories changes.
println!("cargo:rerun-if-changed=src/**/*.scss"); 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.flatten() {
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);
};
} }