use heck::ToPascalCase; use proc_macro2::TokenStream; use quote::quote; use serde::Deserialize; use crate::ident; #[derive(Deserialize, Debug)] pub struct Enchantment { #[allow(unused)] id: u16, name: String, translation_key: String, min_level: i16, max_level: i16, #[serde(alias = "cursed")] is_curse: bool, rarity_weight: i32, #[serde(alias = "sources")] source: EnchantmentSources, } #[derive(Deserialize, Debug)] pub struct EnchantmentSources { treasure: bool, enchantment_table: bool, random_selection: bool, } pub fn build() -> anyhow::Result { let enchants: Vec = serde_json::from_str(include_str!("../extracted/enchants.json"))?; let enchantmentkind_definitions = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let id = enchant.id as isize; quote! { #rustified_name = #id, } }) .collect::(); let enchantmentkind_id_to_variant_lookup = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let id = &enchant.id; quote! { #id => Some(Self::#rustified_name), } }) .collect::(); let enchantmentkind_names = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let name = &enchant.name; quote! { Self::#rustified_name => #name, } }) .collect::(); let enchantmentkind_translations = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let translation_key = &enchant.translation_key; quote! { Self::#rustified_name => #translation_key, } }) .collect::(); let enchantmentkind_min_level = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let min_level = &enchant.min_level; quote! { Self::#rustified_name => #min_level, } }) .collect::(); let enchantmentkind_max_level = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let max_level = &enchant.max_level; quote! { Self::#rustified_name => #max_level, } }) .collect::(); let enchantmentkind_is_curse = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let is_curse = &enchant.is_curse; quote! { Self::#rustified_name => #is_curse, } }) .collect::(); let enchantmentkind_rarity_weight = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let rarity_weight = &enchant.rarity_weight; quote! { Self::#rustified_name => #rarity_weight, } }) .collect::(); let enchantmentkind_sources = enchants .iter() .map(|enchant| { let rustified_name = ident(enchant.name.to_pascal_case()); let treasure = &enchant.source.treasure; let enchantment_table = &enchant.source.enchantment_table; let random_selection = &enchant.source.random_selection; quote! { Self::#rustified_name => EnchantmentSources { treasure: #treasure, enchantment_table: #enchantment_table, random_selection: #random_selection, }, } }) .collect::(); Ok(quote! { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct EnchantmentSources { pub treasure: bool, pub enchantment_table: bool, pub random_selection: bool, } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum EnchantmentKind { #enchantmentkind_definitions } impl EnchantmentKind { /// Constructs an `EnchantmentKind` from a raw enchantment ID. /// /// If the given ID is invalid, `None` is returned. pub const fn from_raw(id: u16) -> Option { match id{ #enchantmentkind_id_to_variant_lookup _ => None } } /// Returns the raw enchantment ID. pub const fn to_raw(self) -> u16 { self as u16 } /// Returns the translation key. pub const fn translation_key(self) -> &'static str { match self{ #enchantmentkind_translations } } /// Returns the enchantment name the game uses. pub const fn name(self) -> &'static str { match self{ #enchantmentkind_names } } /// Returns the minimum enchantment level officially supported by Minecraft. pub const fn min_level(self) -> i16 { match self{ #enchantmentkind_min_level } } /// Returns the maximum enchantment level officially supported by Minecraft. pub const fn max_level(self) -> i16 { match self{ #enchantmentkind_max_level } } /// Returns true if the enchantment is of the curse type. pub const fn is_curse(self) -> bool { match self{ #enchantmentkind_is_curse } } /// Returns the rarity of the enchant. Lower means more rare. pub const fn rarity_weight(self) -> i32 { match self{ #enchantmentkind_rarity_weight } } /// Returns the different sources this enchantment has. pub const fn sources(self) -> EnchantmentSources { match self{ #enchantmentkind_sources } } } }) }