valence/build/entity_event.rs
2022-08-05 12:36:34 -07:00

67 lines
1.8 KiB
Rust

use std::collections::BTreeMap;
use heck::ToPascalCase;
use proc_macro2::TokenStream;
use quote::quote;
use serde::Deserialize;
use crate::ident;
#[derive(Deserialize, Clone, Debug)]
struct EntityData {
statuses: BTreeMap<String, u8>,
animations: BTreeMap<String, u8>,
}
pub fn build() -> anyhow::Result<TokenStream> {
let entity_data: EntityData =
serde_json::from_str(include_str!("../extracted/entity_data.json"))?;
let mut statuses: Vec<_> = entity_data.statuses.into_iter().collect();
statuses.sort_by_key(|(_, id)| *id);
let mut animations: Vec<_> = entity_data.animations.into_iter().collect();
animations.sort_by_key(|(_, id)| *id);
let event_variants = statuses
.iter()
.chain(animations.iter())
.map(|(name, _)| ident(name.to_pascal_case()));
let status_arms = statuses.iter().map(|(name, code)| {
let name = ident(name.to_pascal_case());
quote! {
Self::#name => StatusOrAnimation::Status(#code),
}
});
let animation_arms = animations.iter().map(|(name, code)| {
let name = ident(name.to_pascal_case());
quote! {
Self::#name => StatusOrAnimation::Animation(#code),
}
});
Ok(quote! {
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub enum EntityEvent {
#(#event_variants,)*
}
impl EntityEvent {
pub(crate) fn status_or_animation(self) -> StatusOrAnimation {
match self {
#(#status_arms)*
#(#animation_arms)*
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum StatusOrAnimation {
Status(u8),
Animation(u8),
}
})
}