206 lines
6.7 KiB
Rust
206 lines
6.7 KiB
Rust
#![allow(clippy::unwrap_used, clippy::expect_used)]
|
|
|
|
use std::env;
|
|
use std::fmt::Write;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
|
|
fn main() {
|
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
|
let dest_path = Path::new(&out_dir).join("template_embeddings.rs");
|
|
|
|
let mut code = String::from(
|
|
"
|
|
#[allow(clippy::too_many_lines)]
|
|
#[allow(clippy::match_same_arms)]
|
|
#[must_use]
|
|
pub fn get_template_bytes(path: &str) -> Option<&'static [u8]> {\n match path {\n",
|
|
);
|
|
let mut pool_code = String::from(
|
|
"
|
|
#[allow(clippy::too_many_lines)]
|
|
#[allow(clippy::match_same_arms)]
|
|
#[must_use]
|
|
pub fn get_pool_elements(pool_id: &str) -> Option<&'static [&'static str]> {\n match pool_id {\n",
|
|
);
|
|
let mut template_pool_json_code = String::from(
|
|
"
|
|
#[allow(clippy::too_many_lines)]
|
|
#[allow(clippy::match_same_arms)]
|
|
#[must_use]
|
|
pub fn get_template_pool_json(path: &str) -> Option<&'static str> {\n match path {\n",
|
|
);
|
|
let mut processor_list_json_code = String::from(
|
|
"
|
|
#[allow(clippy::too_many_lines)]
|
|
#[allow(clippy::match_same_arms)]
|
|
#[must_use]
|
|
pub fn get_processor_list_json(path: &str) -> Option<&'static str> {\n match path {\n",
|
|
);
|
|
|
|
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
|
let assets_dir = Path::new(&manifest_dir).join("assets/structures");
|
|
let mut all_template_names: Vec<String> = Vec::new();
|
|
let mut all_pool_names: Vec<String> = Vec::new();
|
|
if assets_dir.exists() {
|
|
let mut pools = std::collections::BTreeMap::new();
|
|
process_dir(
|
|
&assets_dir,
|
|
"",
|
|
&mut code,
|
|
&mut pools,
|
|
&mut all_template_names,
|
|
);
|
|
|
|
for (pool_id, elements) in pools {
|
|
all_pool_names.push(pool_id.clone());
|
|
let _ = writeln!(
|
|
pool_code,
|
|
" \"minecraft:{pool_id}\" | \"{pool_id}\" => Some(&["
|
|
);
|
|
for element in elements {
|
|
let _ = writeln!(pool_code, " \"{element}\",");
|
|
}
|
|
pool_code.push_str(" ]),\n");
|
|
}
|
|
}
|
|
|
|
code.push_str(" _ => None,\n");
|
|
code.push_str(" }\n}\n");
|
|
|
|
// Generate a function returning all available template names (for tab-completion)
|
|
code.push_str(
|
|
"#[must_use]\n#[allow(clippy::too_many_lines, clippy::large_stack_arrays)]\npub const fn _generated_all_template_names() -> &'static [&'static str] {\n &[\n",
|
|
);
|
|
for name in &all_template_names {
|
|
let _ = writeln!(code, " \"{name}\",");
|
|
}
|
|
code.push_str(" ]\n}\n");
|
|
|
|
// Generate a function returning all available pool names (for tab-completion)
|
|
code.push_str(
|
|
"#[must_use]\n#[allow(clippy::too_many_lines, clippy::large_stack_arrays)]\npub const fn _generated_all_pool_names() -> &'static [&'static str] {\n &[\n",
|
|
);
|
|
for name in &all_pool_names {
|
|
let _ = writeln!(code, " \"{name}\",");
|
|
}
|
|
code.push_str(" ]\n}\n");
|
|
|
|
pool_code.push_str(" _ => None,\n");
|
|
pool_code.push_str(" }\n}\n");
|
|
|
|
let worldgen_dir = Path::new(&manifest_dir).join("assets/worldgen");
|
|
process_json_dir(
|
|
&worldgen_dir.join("template_pool"),
|
|
"",
|
|
&mut template_pool_json_code,
|
|
&mut all_pool_names,
|
|
);
|
|
process_json_dir(
|
|
&worldgen_dir.join("processor_list"),
|
|
"",
|
|
&mut processor_list_json_code,
|
|
&mut Vec::new(),
|
|
);
|
|
template_pool_json_code.push_str(" _ => None,\n");
|
|
template_pool_json_code.push_str(" }\n}\n");
|
|
processor_list_json_code.push_str(" _ => None,\n");
|
|
processor_list_json_code.push_str(" }\n}\n");
|
|
|
|
fs::write(
|
|
&dest_path,
|
|
format!("{code}\n{pool_code}\n{template_pool_json_code}\n{processor_list_json_code}"),
|
|
)
|
|
.unwrap();
|
|
println!("cargo:rerun-if-changed=assets/structures");
|
|
println!("cargo:rerun-if-changed=assets/worldgen");
|
|
}
|
|
|
|
fn process_dir(
|
|
dir: &Path,
|
|
prefix: &str,
|
|
code: &mut String,
|
|
pools: &mut std::collections::BTreeMap<String, Vec<String>>,
|
|
names: &mut Vec<String>,
|
|
) {
|
|
for entry in fs::read_dir(dir).unwrap() {
|
|
let entry = entry.unwrap();
|
|
let path = entry.path();
|
|
let name = entry.file_name().into_string().unwrap();
|
|
|
|
if path.is_dir() {
|
|
let new_prefix = if prefix.is_empty() {
|
|
name
|
|
} else {
|
|
format!("{prefix}/{name}")
|
|
};
|
|
process_dir(&path, &new_prefix, code, pools, names);
|
|
} else if path
|
|
.extension()
|
|
.and_then(|s| s.to_str())
|
|
.is_some_and(|ext| ext.eq_ignore_ascii_case("nbt"))
|
|
{
|
|
let stem = path.file_stem().unwrap().to_string_lossy();
|
|
let template_name = if prefix.is_empty() {
|
|
stem.to_string()
|
|
} else {
|
|
format!("{prefix}/{stem}")
|
|
};
|
|
let abs_path = path.canonicalize().unwrap();
|
|
let _ = writeln!(
|
|
code,
|
|
" \"{template_name}\" => Some(include_bytes!(r#\"{abs}\"#)),",
|
|
template_name = template_name,
|
|
abs = abs_path.display()
|
|
);
|
|
names.push(template_name.clone());
|
|
|
|
if !prefix.is_empty() {
|
|
pools
|
|
.entry(prefix.to_string())
|
|
.or_default()
|
|
.push(template_name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn process_json_dir(dir: &Path, prefix: &str, code: &mut String, names: &mut Vec<String>) {
|
|
if !dir.exists() {
|
|
return;
|
|
}
|
|
|
|
let mut entries = fs::read_dir(dir)
|
|
.unwrap()
|
|
.map(Result::unwrap)
|
|
.collect::<Vec<_>>();
|
|
entries.sort_by_key(std::fs::DirEntry::file_name);
|
|
|
|
for entry in entries {
|
|
let path = entry.path();
|
|
let name = entry.file_name().into_string().unwrap();
|
|
if path.is_dir() {
|
|
let new_prefix = if prefix.is_empty() {
|
|
name
|
|
} else {
|
|
format!("{prefix}/{name}")
|
|
};
|
|
process_json_dir(&path, &new_prefix, code, names);
|
|
} else if let Some(stem) = name.strip_suffix(".json") {
|
|
let id = if prefix.is_empty() {
|
|
stem.to_string()
|
|
} else {
|
|
format!("{prefix}/{stem}")
|
|
};
|
|
names.push(id.clone());
|
|
let abs_path = path.canonicalize().unwrap();
|
|
let _ = writeln!(
|
|
code,
|
|
" \"minecraft:{id}\" | \"{id}\" => Some(include_str!(r#\"{abs}\"#)),",
|
|
id = id,
|
|
abs = abs_path.display()
|
|
);
|
|
}
|
|
}
|
|
}
|