JaneDoe-ZS/nap_data/src/tables/mod.rs
2024-08-06 22:58:24 +08:00

101 lines
3.2 KiB
Rust

use paste::paste;
use std::sync::OnceLock;
use super::DataLoadError;
macro_rules! template_id {
($type_name:ident $underlying_type:ident $id_field:ident) => {
::paste::paste! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, ::serde::Deserialize, ::serde::Serialize)]
pub struct [<$type_name ID>]($underlying_type);
impl [<$type_name ID>] {
pub fn new(id: $underlying_type) -> Option<Self> {
if crate::tables::[<$type_name:snake _template_tb>]::iter().any(|tmpl| tmpl.$id_field.value() == id) {
Some(Self(id))
}
else {
None
}
}
pub fn new_unchecked(id: $underlying_type) -> Self {
Self(id)
}
pub fn value(&self) -> $underlying_type {
self.0
}
pub fn template(&self) -> &[<$type_name Template>] {
crate::tables::[<$type_name:snake _template_tb>]::iter().find(|tmpl| tmpl.$id_field == *self).unwrap()
}
}
impl ::std::fmt::Display for [<$type_name ID>] {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
f.write_fmt(format_args!("{}", self.0))
}
}
}
};
}
macro_rules! template_tables {
($($template_type:ident;)*) => {
$(paste! {
mod [<$template_type:snake>];
pub use [<$template_type:snake>]::*;
})*
$(paste! {
static [<$template_type:snake:upper _TB>]: OnceLock<Vec<$template_type>> = OnceLock::new();
})*
pub(crate) fn load_tables(filecfg_path: &str) -> Result<(), DataLoadError> {
$(paste! {
let file_name = concat!(stringify!($template_type), "Tb.json");
let path = format!("{filecfg_path}/{file_name}");
let data = std::fs::read_to_string(path)?;
[<$template_type:snake:upper _TB>].set(serde_json::from_str(&data).map_err(|err| DataLoadError::FromJsonError(String::from(stringify!($template_type)), err))?).unwrap();
})*
Ok(())
}
$(paste! {
pub mod [<$template_type:snake _tb>] {
pub fn iter() -> ::std::slice::Iter<'static, super::$template_type> {
super::[<$template_type:snake:upper _TB>].get().unwrap().iter()
}
}
})*
};
}
template_tables! {
AvatarBaseTemplate;
UnlockConfigTemplate;
SectionConfigTemplate;
ProcedureConfigTemplate;
PostGirlConfigTemplate;
TrainingQuestTemplate;
WeaponTemplate;
MainCityObjectTemplate;
MainCityDefaultObjectTemplate;
MainCityBgmConfigTemplate;
ArchiveFileQuestTemplate;
ArchiveBattleQuestTemplate;
HollowQuestTemplate;
HollowConfigTemplate;
BattleEventConfigTemplate;
BattleGroupConfigTemplate;
SubAreaDataTemplate;
VariableDataTemplate;
OnceRewardTemplate;
QuickAccessTemplate;
QuickFuncTemplate;
TeleportConfigTemplate;
ItemTemplate;
}