cwe-data 1.0.0

Request CWE data offline
use std::fs;
use std::io::Write;
use std::path::PathBuf;

const CWE_JSON_URL: &str =
    "https://raw.githubusercontent.com/CWE-CAPEC/REST-API-wg/refs/heads/main/json_repo/cwe.json";

fn main() {
    let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
    let data_dir = out_dir.join("data");
    let cwe_json = out_dir.join("cwe.json");

    if !cwe_json.exists() {
        let response = reqwest::blocking::get(CWE_JSON_URL).expect("Failed to download cwe.json");

        if !response.status().is_success() {
            panic!("Failed to download cwe.json: HTTP {}", response.status());
        }

        let bytes = response.bytes().expect("Failed to read response body");
        let mut file = fs::File::create(&cwe_json).expect("Failed to create cwe.json");
        file.write_all(&bytes).expect("Failed to write cwe.json");
    }

    fs::create_dir_all(&data_dir).expect("Failed to create data directory");

    let content = fs::read_to_string(cwe_json).expect("Failed to read cwe.json");
    let json: serde_json::Value = serde_json::from_str(&content).expect("Failed to parse cwe.json");

    for section in ["Weaknesses", "Categories", "Views"] {
        if let Some(items) = json[section].as_array() {
            for item in items {
                if let Some(id) = item["ID"].as_str() {
                    let mut filtered = item.clone();
                    if let Some(obj) = filtered.as_object_mut() {
                        obj.remove("ContentHistory");
                    }

                    let filepath = data_dir.join(format!("CWE-{}.json", id));
                    let pretty_json =
                        serde_json::to_string_pretty(&filtered).expect("Failed to serialize");
                    fs::write(&filepath, &pretty_json).expect("Failed to write file");
                }
            }
        }
    }

    println!("cargo:rerun-if-changed=cwe.json");
    println!("cargo:rerun-if-changed=build.rs");
}