Gen7ScriptsRs/gen_7_scripts/build.rs

128 lines
3.5 KiB
Rust

use std::io::Write;
fn main() {
let mut output_file = std::fs::File::create("src/registered_scripts.rs").unwrap();
write!(
output_file,
r"// Autogenerated file. Do not edit.
use alloc::boxed::Box;
use pkmn_lib_interface::app_interface::{{get_hash, StringKey}};
use pkmn_lib_interface::handling::{{Script, ScriptCategory}};
macro_rules! resolve_match {{
(
$mid:expr,
$(
$script:ty,
)*
) => (
match $mid {{
$(
const {{ get_hash(<$script>::get_const_name()) }} => {{
return Some(Box::new(<$script>::new()))
}}
)*
_ => {{}}
}}
)
}}
pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn Script>> {{
match category {{"
)
.unwrap();
write_category("moves", "Move", &mut output_file);
write_category("abilities", "Ability", &mut output_file);
write_category("status", "Status", &mut output_file);
write_category("pokemon", "Pokemon", &mut output_file);
write_category("battle", "Battle", &mut output_file);
write_category("weather", "Weather", &mut output_file);
write_category("side", "Side", &mut output_file);
write_category(
"item_battle_triggers",
"ItemBattleTrigger",
&mut output_file,
);
write!(
output_file,
r#"
}}
None
}}
"#
)
.unwrap();
}
fn write_category(path: &str, category: &str, output_file: &mut std::fs::File) {
write!(
output_file,
r"
ScriptCategory::{} => {{
resolve_match! {{
name.hash().unwrap(),
",
category
)
.unwrap();
write_scripts(path, output_file);
write!(
output_file,
r" }}
}},"
)
.unwrap();
}
fn write_scripts(path: &str, output_file: &mut std::fs::File) {
let move_files = std::fs::read_dir(format!("src/{}", path))
.unwrap()
.map(|f| f.unwrap().path())
.filter(|f| f.extension().unwrap() == "rs")
.map(|f| f.file_stem().unwrap().to_str().unwrap().to_string())
.collect::<Vec<_>>();
for file in move_files {
println!("cargo:rerun-if-changed=src/{}/{}.rs", path, file);
let parsed =
syn::parse_file(&std::fs::read_to_string(format!("src/{}/{}.rs", path, file)).unwrap())
.unwrap();
// Now we need to find every impl Script for X { ... } block inside parsed
let script_impls = parsed
.items
.iter()
.filter_map(|item| match item {
syn::Item::Impl(impl_block) => match impl_block.trait_ {
Some((_, ref path, _)) => {
if path.segments[0].ident == "Script" {
Some(impl_block)
} else {
None
}
}
None => None,
},
_ => None,
})
.collect::<Vec<_>>();
for script_impl in script_impls {
match script_impl.self_ty.as_ref() {
syn::Type::Path(p) => {
let ident = p.path.segments[0].ident.to_string();
writeln!(
output_file,
" crate::{}::{}::{},",
path, file, ident
)
.unwrap();
}
_ => {}
}
}
}
}