//! Build script. //! //! Generates the indexed record collection list from the authored lexicons. //! Server-side runtime configuration is loaded by the server binary via //! `dotenvy` and read into a typed `ServerConfig` struct (see //! `src/indexing/config.rs`); no environment values are embedded in frontend //! artifacts here. use serde_json::Value; use std::env; use std::fs::{self, File}; use std::io::Write; use std::path::{Path, PathBuf}; fn main() { generate_indexed_collections(); } fn generate_indexed_collections() { println!("cargo:rerun-if-changed=lexicons"); let lexicon_root = Path::new("lexicons"); let mut json_paths = Vec::new(); collect_json_paths(lexicon_root, &mut json_paths); json_paths.sort(); let mut collections = Vec::new(); for path in json_paths { println!("cargo:rerun-if-changed={}", path.display()); let contents = fs::read_to_string(&path) .unwrap_or_else(|e| panic!("read authored lexicon {}: {e}", path.display())); let lexicon: Value = serde_json::from_str(&contents) .unwrap_or_else(|e| panic!("parse authored lexicon JSON {}: {e}", path.display())); if lexicon.pointer("/defs/main/type").and_then(Value::as_str) != Some("record") { continue; } let id = lexicon .get("id") .and_then(Value::as_str) .unwrap_or_else(|| panic!("record lexicon {} has no string id", path.display())); if id.starts_with("space.polymodel.") { collections.push(id.to_owned()); } } collections.sort(); let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR set by Cargo")); let out_path = out_dir.join("polymodel_record_collections.rs"); let mut out = File::create(&out_path) .unwrap_or_else(|e| panic!("create generated collections {}: {e}", out_path.display())); writeln!(out, "// Generated by build.rs from authored lexicons where defs.main.type == \"record\".\n// Do not edit.\npub const INDEXED_COLLECTIONS: &[&str] = &[").expect("write generated collections header"); for collection in collections { writeln!(out, " {collection:?},").expect("write generated collection"); } writeln!(out, "];").expect("write generated collections footer"); } fn collect_json_paths(dir: &Path, paths: &mut Vec) { let entries = fs::read_dir(dir).unwrap_or_else(|e| panic!("read lexicon dir {}: {e}", dir.display())); for entry in entries { let entry = entry.unwrap_or_else(|e| panic!("read lexicon dir entry in {}: {e}", dir.display())); let path = entry.path(); if path.is_dir() { collect_json_paths(&path, paths); } else if path.extension().and_then(|ext| ext.to_str()) == Some("json") { paths.push(path); } } }