use {vkgen::*, std::{io::{self, Write}, fs::{File, OpenOptions}}};
const HELP: &str = r#"
vkgen
Usage: vkgen <input file (optional)> [options]
If no input file is specified, the registry will be read from stdin.
Options:
--help, -h - display this help page
--out=<output file>,
-o=<output file> - specify the output file, if no output file is specified, the generated code will be written to `<input file>.rs`
--out-cargo=<output cargo file>,
-oc=<output cargo file> - specify the output cargo file, if no output file is specified, the generated code will be written to `<input file>.toml`
For more information, see https://crates.io/crates/vkgen
"#;
fn main() {
let mut file_in = None;
let mut file_out = None;
let mut file_out_cargo = None;
for arg in std::env::args().skip(1) {
if arg.starts_with('-') {
if arg.starts_with("-o=") || arg.starts_with("--out=") {
file_out = Some(arg.trim_start_matches("-o=")
.trim_start_matches("--out=").to_string());
} else if arg.starts_with("-oc=") || arg.starts_with("--out-cargo=") {
file_out_cargo = Some(arg.trim_start_matches("-oc=")
.trim_start_matches("--out-cargo=").to_string());
} else if arg == "-h" || arg == "--help" {
println!("{}", HELP);
return;
} else {
println!("ignored unknown option: {}", arg)
}
} else {
file_in = Some(arg);
}
}
let r = match &file_in {
Some(file_in) => {
print!("parsing file `{}` ... ", file_in);
std::io::stdout().flush().unwrap_or_default();
xml::deserialize(File::open(file_in)
.map(io::BufReader::new)
.expect("failed to open input file"))
}
None => {
print!("parsing from stdin ... ");
std::io::stdout().flush().unwrap_or_default();
xml::deserialize(io::BufReader::new(io::stdin()))
}
};
let Registry { api, elements, exts } = match r {
Ok(v) => {
println!("\x1b[32mok\x1b[0m");
v
}
Err(e) => {
println!("\x1b[31mfailed\x1b[0m\nError: {}", e);
std::process::exit(100);
}
};
let file_out = file_out
.or_else(|| file_in.as_ref().map(|s| s.replace(".xml", ".rs")))
.unwrap_or_else(|| match api {
Api::Vulkan => "vk.rs",
Api::OpenXr => "xr.rs"
}.to_string());
print!("generating code (dst: `{}`) ... ", &file_out);
std::io::stdout().flush().unwrap_or_default();
let r = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(&file_out)
.and_then(|writer| gen::gen(&mut io::BufWriter::new(writer), elements.into_iter(), api, true));
match r {
Ok(()) => println!("\x1b[32mok\x1b[0m"),
Err(e) => {
println!("\x1b[31mfailed\x1b[0m\nError: {}", e);
std::process::exit(100);
}
}
let file_out_cargo = file_out_cargo
.or_else(|| file_in.as_ref().map(|s| s.replace(".xml", ".toml")))
.unwrap_or_else(|| match api {
Api::Vulkan => "vk.toml",
Api::OpenXr => "xr.toml"
}.to_string());
print!("generating cargo file (dst: `{}`) ... ", &file_out_cargo);
std::io::stdout().flush().unwrap_or_default();
let r = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(&file_out_cargo)
.and_then(|writer| gen::gen_cargo(&mut io::BufWriter::new(writer), exts));
match r {
Ok(()) => println!("\x1b[32mok\x1b[0m"),
Err(e) => {
println!("\x1b[31mfailed\x1b[0m\nError: {}", e);
std::process::exit(100);
}
}
if BITFIELDS.load(std::sync::atomic::Ordering::Relaxed) {
println!("WARN: the registry contains C bitfield structs, these structs are not generated correctly! See the README for more information.");
}
print!("fixing pointer types ... ");
std::io::stdout().flush().unwrap_or_default();
match vkgen::fix_ptr_types(api, &file_out) {
Ok(()) => println!("\x1b[32mok\x1b[0m"),
Err(e) => {
println!("\x1b[31mfailed\x1b[0m\nError: {}", e);
std::process::exit(100);
}
}
}