use quote::ToTokens;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct GeneratedType {
header: String,
name: String,
source: String,
}
fn gen_cxx_sources(folder: &str, file_stem: &str) -> GeneratedType {
let path = format!("{}/{}.rs", folder, file_stem);
println!("cargo:rerun-if-changed={}", path);
let content = std::fs::read_to_string(path).expect("Could not read Rust file");
let file = syn::parse_file(&content).unwrap();
let opt = cxx_gen::Opt::default();
let generated = cxx_gen::generate_header_and_cc(file.into_token_stream(), &opt)
.expect("Could not generate C++ from Rust file");
GeneratedType {
header: String::from_utf8(generated.header).unwrap(),
name: format!("{}_cxx", file_stem),
source: String::from_utf8(generated.implementation).unwrap(),
}
}
fn write_cxx_sources(gen: Vec<GeneratedType>, path: &str) {
let file = std::fs::File::create(path).expect("Could not create generated file");
serde_json::to_writer(file, &gen).unwrap();
}
fn main() {
let mut dir_manifest = std::env::var("CARGO_MANIFEST_DIR").expect("Could not get manifest dir");
if cfg!(windows) {
dir_manifest = dir_manifest.replace('\\', "/");
}
println!("cargo:rerun-if-env-changed=CARGO_MANIFEST_DIR");
let mut dir_out = std::env::var("OUT_DIR").expect("Could not get out dir");
if cfg!(windows) {
dir_out = dir_out.replace('\\', "/");
}
println!("cargo:rerun-if-env-changed=OUT_DIR");
let path = format!("{}/cxx-qt-lib", dir_out);
std::fs::create_dir_all(&path).expect("Could not create cxx-qt-lib dir");
let types_dir = format!("{}/src/types/", dir_manifest);
println!("cargo:rerun-if-changed={}", types_dir);
let mut generated = vec![];
for entry in std::fs::read_dir(&types_dir).expect("Could not open types folder") {
let path = entry.expect("Could not open file").path();
let file_stem = path
.file_stem()
.expect("Could not find file name")
.to_str()
.expect("Could not convert to unicode");
if path.is_file() && file_stem != "mod" {
generated.push(gen_cxx_sources(&types_dir, file_stem));
}
}
write_cxx_sources(generated, &format!("{}/qt_types_cxx.json", path));
}