diff options
Diffstat (limited to 'ecs-macros/src')
-rw-r--r-- | ecs-macros/src/lib.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/ecs-macros/src/lib.rs b/ecs-macros/src/lib.rs new file mode 100644 index 0000000..e37d6a4 --- /dev/null +++ b/ecs-macros/src/lib.rs @@ -0,0 +1,79 @@ +use proc_macro::TokenStream; +use quote::{quote, ToTokens}; +use syn::spanned::Spanned; +use syn::{parse, Ident, Item, ItemEnum, ItemStruct, ItemUnion}; + +#[proc_macro_derive(Component)] +pub fn component_derive(input: TokenStream) -> TokenStream +{ + let item: TypeItem = parse::<Item>(input).unwrap().try_into().unwrap(); + + let item_ident = item.ident(); + + quote! { + impl ecs::component::Component for #item_ident + { + fn as_any_mut(&mut self) -> &mut dyn std::any::Any + { + self + } + + fn as_any(&self) -> &dyn std::any::Any + { + self + } + } + + impl ecs::system::Input for #item_ident {} + } + .into() +} + +enum TypeItem +{ + Struct(ItemStruct), + Enum(ItemEnum), + Union(ItemUnion), +} + +impl TypeItem +{ + fn ident(&self) -> &Ident + { + match self { + Self::Struct(struct_item) => &struct_item.ident, + Self::Enum(enum_item) => &enum_item.ident, + Self::Union(union_item) => &union_item.ident, + } + } +} + +impl TryFrom<Item> for TypeItem +{ + type Error = syn::Error; + + fn try_from(item: Item) -> Result<Self, Self::Error> + { + match item { + Item::Struct(struct_item) => Ok(Self::Struct(struct_item)), + Item::Enum(enum_item) => Ok(Self::Enum(enum_item)), + Item::Union(union_item) => Ok(Self::Union(union_item)), + _ => Err(syn::Error::new( + item.span(), + "Expected a struct, a enum or a union", + )), + } + } +} + +impl ToTokens for TypeItem +{ + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) + { + match self { + Self::Struct(struct_item) => struct_item.to_tokens(tokens), + Self::Enum(enum_item) => enum_item.to_tokens(tokens), + Self::Union(union_item) => union_item.to_tokens(tokens), + } + } +} |