#![allow(dead_code)]
use once_cell::sync::Lazy;
use ron::de::from_str;
use serde::de::DeserializeOwned;
use std::fs;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
static WORKSPACE_ROOT: Lazy<PathBuf> = Lazy::new(|| {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
manifest_dir
.join("../..")
.canonicalize()
.expect("workspace root")
});
static PROJECT_ROOT: Lazy<PathBuf> = Lazy::new(|| WORKSPACE_ROOT.join("projects/example_mod"));
pub fn read_string(path: &Path) -> String {
fs::read_to_string(path)
.unwrap_or_else(|err| panic!("Failed to read {}: {err}", path.display()))
}
pub fn project_root() -> &'static Path {
PROJECT_ROOT.as_path()
}
pub fn parse_project_ron<T>(relative: &str) -> T
where
T: DeserializeOwned,
{
let path = PROJECT_ROOT.join(relative);
let contents = fs::read_to_string(&path)
.unwrap_or_else(|err| panic!("Failed to read {}: {err}", path.display()));
from_str(&contents).unwrap_or_else(|err| panic!("Failed to parse {}: {err}", path.display()))
}
pub fn ensure_project_asset(relative: &str) {
let path = PROJECT_ROOT.join(relative);
if !path.exists() {
panic!("Asset {} missing", path.display());
}
}
pub fn list_project_files_with_suffix(relative_dir: &str, suffix: &str) -> Vec<String> {
let mut files = Vec::new();
let base = PROJECT_ROOT.join(relative_dir);
if base.exists() {
for entry in WalkDir::new(&base)
.into_iter()
.filter_map(Result::ok)
.filter(|e| e.file_type().is_file())
{
let path = entry.path();
if path.to_string_lossy().ends_with(suffix) {
let relative = path
.strip_prefix(PROJECT_ROOT.as_path())
.unwrap()
.to_string_lossy()
.replace('\\', "/");
files.push(relative);
}
}
}
files.sort();
files
}