diff --git a/Cargo.toml b/Cargo.toml
index f548ef5..be469de 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,3 +31,5 @@ futures = "0.3.29"
[build]
target = "x86_64-unknown-linux-gnu"
+[build-dependencies]
+regex = "1.10.3"
diff --git a/build.rs b/build.rs
index 30524a9..785f8c1 100644
--- a/build.rs
+++ b/build.rs
@@ -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() {
// 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
(filename: P) -> io::Result>>
+where
+ P: AsRef,
+{
+ 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);
+ };
}