♻️ Use of the SCSS variables to compute the width of the inner panels

This commit is contained in:
2024-06-08 13:04:17 +02:00
parent 1ad4d444fb
commit d566a4927f
8 changed files with 132 additions and 54 deletions

138
build.rs
View File

@@ -1,4 +1,5 @@
use std::env;
use std::fmt::Display;
use std::fs::File;
use std::io::Write;
use std::io::{self, BufRead};
@@ -10,14 +11,32 @@ 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");
println!("cargo:rerun-if-changed=src/ui/**/*.scss");
let out_dir = env::var("OUT_DIR").unwrap();
let style_src_path = PathBuf::from("src/ui/_base.scss");
let style_dst_path = Path::new(&out_dir).join("style_vars.rs");
let mut tasks = Vec::new();
export_color_variables(&style_src_path, &style_dst_path)
// Global tokens
tasks.push(Task::new(
PathBuf::from("src/ui/_base.scss"),
Path::new(&out_dir).join("style_tokens.rs"),
"style".to_string(),
));
// variables defined by the Panel component
tasks.push(Task::new(
PathBuf::from("src/ui/components/_panel.scss"),
Path::new(&out_dir).join("style_component_panel.rs"),
"panel".to_string(),
));
// Variables set by the Conversations layout
tasks.push(Task::new(
PathBuf::from("src/ui/layouts/conversations.scss"),
Path::new(&out_dir).join("style_layout_conversations.rs"),
"conversations".to_string(),
));
export_variables(tasks)
}
// From https://doc.rust-lang.org/rust-by-example/std_misc/file/read_lines.html
@@ -32,14 +51,21 @@ where
}
#[derive(Debug)]
struct CssColorVariable<'a> {
name: &'a str,
value: &'a str,
struct ColorVariable {
name: String,
value: String,
}
impl<'a> CssColorVariable<'a> {
pub fn to_rust(&self) -> String {
format!(
impl ColorVariable {
pub fn new(name: String, value: String) -> Self {
Self { name, value }
}
}
impl Display for ColorVariable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"const {name}: &str = \"{value}\";",
name = self.name.replace('-', "_").to_uppercase(),
value = self.value
@@ -47,35 +73,83 @@ impl<'a> CssColorVariable<'a> {
}
}
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;
};
#[derive(Debug)]
struct FloatVariable {
name: String,
value: f64,
}
let re = Regex::new(r"^\$([^:]+):[[:space:]]*#([^$]+);[[:space:]]*$").unwrap();
impl FloatVariable {
pub fn new(name: String, value: f64) -> Self {
Self { name, value }
}
}
if let Ok(lines) = read_lines(src_path) {
for line in lines.map_while(Result::ok) {
let Some(groups) = re.captures(&line) else {
continue;
};
impl Display for FloatVariable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"const {name}: f64 = {value};",
name = self.name.replace('-', "_").to_uppercase(),
value = self.value
)
}
}
let var = CssColorVariable {
name: &groups[1],
value: &groups[2],
};
struct Task {
src_path: PathBuf,
dst_path: PathBuf,
module_name: String,
}
let rust_export = var.to_rust();
if let Err(err) = dst_file.write_fmt(format_args!(" pub {}\n", rust_export)) {
impl Task {
pub fn new(src_path: PathBuf, dst_path: PathBuf, module_name: String) -> Self {
Self {
src_path,
dst_path,
module_name,
}
}
}
// fn export_variables(src_path: &PathBuf, dst_path: &PathBuf) {
fn export_variables(tasks: Vec<Task>) {
let color_re = Regex::new(r"^\$([^:]+):[[:space:]]*#([^$]+);[[:space:]]*$").unwrap();
let variable_re = Regex::new(r"^\$([^:]+):[[:space:]]*([^;]+)[[:space:]]*;").unwrap();
for task in tasks {
let mut dst_file = File::create(task.dst_path).unwrap();
if let Err(err) = dst_file.write_fmt(format_args!(
"#[allow(dead_code)]\nmod {} {{\n",
task.module_name
)) {
println!("{}", err);
return;
};
let mut variables = Vec::<Box<dyn Display>>::new();
if let Ok(lines) = read_lines(task.src_path) {
for line in lines.map_while(Result::ok) {
if let Some(groups) = color_re.captures(&line) {
let var = ColorVariable::new(groups[1].to_string(), groups[2].to_string());
variables.push(Box::new(var));
} else if let Some(groups) = variable_re.captures(&line) {
if let Ok(value) = groups[2].parse::<f64>() {
variables.push(Box::new(FloatVariable::new(groups[1].to_string(), value)));
}
}
}
}
for variable in variables {
if let Err(err) = dst_file.write_fmt(format_args!(" pub {}\n", variable)) {
println!("{}", err);
break;
}
}
}
if let Err(err) = dst_file.write(b"}\n") {
println!("{}", err);
};
if let Err(err) = dst_file.write(b"}\n") {
println!("{}", err);
};
}
}