use serde::Deserialize;
use std::collections::BTreeMap;
use std::sync::OnceLock;
#[derive(Debug, Deserialize, Clone, Default)]
pub struct Palette {
pub bg: String,
pub white: String,
pub acid_green: String,
pub hot_pink: String,
pub purple: String,
pub cyan: String,
pub orange: String,
pub red: String,
pub panel: String,
pub line: String,
pub muted: String,
}
#[derive(Debug, Deserialize)]
pub struct Schema {
pub schema_version: u32,
pub active: String,
pub themes: BTreeMap<String, Palette>,
pub paths: Paths,
#[serde(skip)]
pub palette: Palette,
}
impl Schema {
pub fn theme(&self, name: &str) -> Option<&Palette> {
self.themes.get(name)
}
pub fn active_theme(&self) -> &Palette {
self.themes
.get(&self.active)
.or_else(|| self.themes.values().next())
.expect("cybergrid.json defines no themes")
}
pub fn theme_names(&self) -> impl Iterator<Item = &str> {
self.themes.keys().map(String::as_str)
}
}
#[derive(Debug, Deserialize)]
pub struct Paths {
pub sysops_root: String,
pub cargo_target_root: String,
pub arch_sys_root: String,
pub omarchy_config_root: String,
}
static SCHEMA: OnceLock<Schema> = OnceLock::new();
const RAW: &str = include_str!(concat!(env!("OUT_DIR"), "/cybergrid_merged.json"));
pub fn load() -> &'static Schema {
SCHEMA.get_or_init(|| {
let mut s: Schema = serde_json::from_str(RAW).expect(
"schema/cybergrid.json failed to parse — this is a cybercore bug, \
not a caller error, since the schema is embedded at compile time",
);
if let Ok(name) = std::env::var("CYBERGRID_THEME") {
if !name.is_empty() && s.themes.contains_key(&name) {
s.active = name;
}
}
s.palette = s
.themes
.get(&s.active)
.or_else(|| s.themes.values().next())
.cloned()
.expect("cybergrid.json defines no themes");
s
})
}