use std::env;
use std::fs;
use std::path::PathBuf;
fn main() {
generate_bundled_source_manifest().unwrap_or_else(|error| panic!("{error}"));
}
fn generate_bundled_source_manifest() -> Result<(), String> {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let bundled_dir = manifest_dir.join("indicators/sources");
println!("cargo:rerun-if-changed=indicators/sources");
let mut source_files = Vec::new();
for entry in fs::read_dir(&bundled_dir).map_err(|error| {
format!(
"{}: could not read bundled indicators: {error}",
bundled_dir.display()
)
})? {
let entry = entry.map_err(|error| {
format!(
"{}: could not inspect bundled indicator entry: {error}",
bundled_dir.display()
)
})?;
let path = entry.path();
if entry
.file_type()
.map_err(|error| format!("{}: could not inspect entry: {error}", path.display()))?
.is_file()
&& path.extension().and_then(|extension| extension.to_str()) == Some("ind")
{
source_files.push(path);
}
}
source_files.sort();
if source_files.is_empty() {
return Err(format!(
"{} contains no bundled indicator .ind sources",
bundled_dir.display()
));
}
let out_dir = env::var_os("OUT_DIR").expect("Cargo should provide OUT_DIR");
let destination = PathBuf::from(out_dir).join("indicator_bundled_sources.rs");
let mut generated = String::from(
"// Generated by build.rs; edit the source files under indicators/sources instead.\n\n",
);
generated.push_str("const BUNDLED_SOURCES: &[BundledSource] = &[\n");
for path in source_files {
let file_name = path
.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| {
format!(
"{}: bundled source filename is not valid UTF-8",
path.display()
)
})?;
let include_path = format!("/indicators/sources/{file_name}");
println!("cargo:rerun-if-changed={}", path.display());
generated.push_str(&format!(
" BundledSource {{\n file_name: {file_name:?},\n source: include_str!(concat!(env!(\"CARGO_MANIFEST_DIR\"), {include_path:?})),\n }},\n"
));
}
generated.push_str("];\n");
fs::write(&destination, generated).map_err(|error| {
format!(
"could not generate bundled indicator source manifest {}: {error}",
destination.display()
)
})
}