saja 0.1.0

Zero-configuration C build system
/*
 * Generate header files in .saja/include/ from a list of exports.
 *
 * Copyright (C) 2026  Madeleine Choi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

use std::collections::BTreeMap;
use std::fs;
use std::path::{Path, PathBuf};

use crate::Saja;
use crate::exports::Export;

impl Saja {
    pub fn make_headers(&self, exports: Vec<Export>, out: &Path) -> anyhow::Result<()> {
        let mut modules: BTreeMap<PathBuf, Vec<Export>> = BTreeMap::new();

        for export in exports {
            modules
                .entry(export.module.clone())
                .or_default()
                .push(export);
        }

        for (module, exports) in modules {
            let mut path = out.join(module);
            path.set_extension("h");

            if let Some(parent) = path.parent() {
                fs::create_dir_all(parent)?;
            }

            let mut contents = String::new();

            contents.push_str("#pragma once\n");

            for export in exports {
                contents.push_str(&export.forward());
                contents.push('\n');
            }

            fs::write(path, contents)?;
        }

        Ok(())
    }
}