flowsurface-data 0.9.0

Data aggregation, indexing, and configuration utilities for Flowsurface
Documentation
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()
        )
    })
}