115 lines
3.6 KiB
Rust
115 lines
3.6 KiB
Rust
use heck::ToPascalCase;
|
|
use indexmap::IndexMap;
|
|
use proc_macro2::TokenStream;
|
|
use quote::{format_ident, quote};
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Deserialize)]
|
|
struct CustomStatisticEntry {
|
|
id: i32,
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct StatisticData {
|
|
id: i32,
|
|
registry: String,
|
|
entries: IndexMap<String, CustomStatisticEntry>,
|
|
}
|
|
|
|
pub fn build() -> TokenStream {
|
|
let stats_json =
|
|
std::fs::read_to_string("../assets/stats.json").expect("Failed to read stats.json");
|
|
let stats_data: IndexMap<String, StatisticData> =
|
|
serde_json::from_str(&stats_json).expect("Failed to parse stats.json");
|
|
|
|
let mut category_variants = Vec::new();
|
|
let mut category_from_id_arms = Vec::new();
|
|
let mut category_from_name_arms = Vec::new();
|
|
let mut custom_stat_variants = Vec::new();
|
|
let mut custom_stat_from_id_arms = Vec::new();
|
|
|
|
for (category_name, data) in &stats_data {
|
|
let category_ident = format_ident!(
|
|
"{}",
|
|
category_name.replace("minecraft:", "").to_pascal_case()
|
|
);
|
|
let category_id = data.id;
|
|
category_variants.push(quote! { #category_ident = #category_id });
|
|
category_from_id_arms.push(quote! { #category_id => Some(Self::#category_ident) });
|
|
let category_name_stripped = category_name.replace("minecraft:", "");
|
|
category_from_name_arms
|
|
.push(quote! { #category_name_stripped => Some(Self::#category_ident) });
|
|
|
|
if category_name == "minecraft:custom" {
|
|
for (stat_name, entry) in &data.entries {
|
|
let stat_ident =
|
|
format_ident!("{}", stat_name.replace("minecraft:", "").to_pascal_case());
|
|
let stat_id = entry.id;
|
|
custom_stat_variants.push(quote! { #stat_ident = #stat_id });
|
|
custom_stat_from_id_arms.push(quote! { #stat_id => Some(Self::#stat_ident) });
|
|
}
|
|
}
|
|
}
|
|
|
|
quote! {
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
#[repr(i32)]
|
|
pub enum StatisticCategory {
|
|
#(#category_variants,)*
|
|
}
|
|
|
|
impl StatisticCategory {
|
|
#[must_use]
|
|
pub const fn from_i32(id: i32) -> Option<Self> {
|
|
match id {
|
|
#(#category_from_id_arms,)*
|
|
_ => None,
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn from_registry_key(name: &str) -> Option<Self> {
|
|
let name = name.strip_prefix("minecraft:").unwrap_or(name);
|
|
match name {
|
|
#(#category_from_name_arms,)*
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<i32> for StatisticCategory {
|
|
type Error = ();
|
|
|
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
Self::from_i32(value).ok_or(())
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
#[repr(i32)]
|
|
pub enum CustomStatistic {
|
|
#(#custom_stat_variants,)*
|
|
}
|
|
|
|
impl CustomStatistic {
|
|
#[must_use]
|
|
pub const fn from_i32(id: i32) -> Option<Self> {
|
|
match id {
|
|
#(#custom_stat_from_id_arms,)*
|
|
_ => None,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<i32> for CustomStatistic {
|
|
type Error = ();
|
|
|
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
|
Self::from_i32(value).ok_or(())
|
|
}
|
|
}
|
|
}
|
|
}
|