use std::{env, fs, path::Path}; use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct Highlight { pub fg: Option, pub bg: Option, pub sp: Option, /// If set, this highlight group is linked to a different group, taking its colors. The other /// attributes will be ignored. pub link: Option, // GUI styles pub bold: Option, pub italic: Option, pub underline: Option, pub undercurl: Option, pub underdouble: Option, pub underdotted: Option, pub underdashed: Option, pub strikethrough: Option, pub reverse: Option, pub nocombine: Option, } struct ThemeElement<'s>(&'s str); impl std::fmt::Display for ThemeElement<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let (namespace, element_name) = self.0.split_once('.').unwrap(); write!( f, r#"NamespacedThemeElement {{ theme_namespace: "{namespace}", element_name: "{element_name}", }}"# ) } } fn main() -> anyhow::Result<()> { use std::io::Write; println!("cargo::rerun-if-changed=./default_highlights"); let out_dir = env::var_os("OUT_DIR").unwrap(); let dest_path = Path::new(&out_dir).join("default_highlights.rs"); let mut code = fs::File::create(dest_path)?; writeln!( code, "pub static DEFAULT_HIGHLIGHTS: &'static [(&'static str, Highlight<'static>)] = &[" )?; for path in fs::read_dir("./default_highlights")? { let path = path?.path(); if !path.is_file() { continue; } let default_highlights = std::fs::read_to_string(path)?; let table: toml::Table = toml::from_str(&default_highlights)?; for (highlight_group, value) in table { writeln!(code, "(")?; writeln!(code, r#""{highlight_group}","#)?; writeln!(code, "Highlight {{")?; for (key, value) in value .as_table() .expect("highlight value must be a TOML table") { match key.as_str() { "fg" | "bg" | "sp" => { let theme_element = ThemeElement(value.as_str().expect("fg, bg and sp values must be str")); writeln!(code, " {key}: Some({theme_element}),")?; } "link" => { let link = value.as_str().expect("link must be str"); writeln!(code, " link: Some({link:?}),")?; } _ => { let attr_value = value.as_bool().expect("highlight attributes must be bool"); writeln!(code, " {key}: Some({attr_value}),")?; } } } writeln!(code, " ..Highlight::empty()")?; writeln!(code, "}}")?; writeln!(code, "),")?; } } writeln!(code, "];")?; Ok(()) }