summaryrefslogtreecommitdiff
path: root/ecs-macros/src/lib.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-04-11 19:03:11 +0200
committerHampusM <hampus@hampusmat.com>2024-04-11 19:07:12 +0200
commitf2120591b0051d4239de73960709248456e884e7 (patch)
tree199bb429e5b64b7362b7cf9c8afcedfba42282f8 /ecs-macros/src/lib.rs
parentd435d9b80c46f995d56d385bc8a0de29e6d865cb (diff)
feat(ecs-macros): add drop_last attribute to Sole derive macro
Diffstat (limited to 'ecs-macros/src/lib.rs')
-rw-r--r--ecs-macros/src/lib.rs69
1 files changed, 58 insertions, 11 deletions
diff --git a/ecs-macros/src/lib.rs b/ecs-macros/src/lib.rs
index 73709e4..dcc6d99 100644
--- a/ecs-macros/src/lib.rs
+++ b/ecs-macros/src/lib.rs
@@ -37,7 +37,9 @@ pub fn component_derive(input: TokenStream) -> TokenStream
let item_ident = item.ident();
- let component_attr = item.component_attribute().unwrap_or_default();
+ let component_attr = item
+ .attribute::<ComponentAttribute>("component")
+ .unwrap_or_default();
let drop_last = component_attr.drop_last;
@@ -46,7 +48,8 @@ pub fn component_derive(input: TokenStream) -> TokenStream
quote! {
impl #ecs_path::component::Component for #item_ident
{
- fn drop_last(&self) -> bool {
+ fn drop_last(&self) -> bool
+ {
#drop_last
}
@@ -74,18 +77,27 @@ pub fn component_derive(input: TokenStream) -> TokenStream
.into()
}
-#[proc_macro_derive(Sole)]
+#[proc_macro_derive(Sole, attributes(sole))]
pub fn sole_derive(input: TokenStream) -> TokenStream
{
let item: TypeItem = parse::<Item>(input).unwrap().try_into().unwrap();
let item_ident = item.ident();
+ let sole_attr = item.attribute::<SoleAttribute>("sole").unwrap_or_default();
+
+ let drop_last = sole_attr.drop_last;
+
let ecs_path = find_engine_ecs_crate_path().unwrap_or_else(|| syn_path!(ecs));
quote! {
impl #ecs_path::sole::Sole for #item_ident
{
+ fn drop_last(&self) -> bool
+ {
+ #drop_last
+ }
+
fn as_any_mut(&mut self) -> &mut dyn std::any::Any
{
self
@@ -108,6 +120,11 @@ pub fn sole_derive(input: TokenStream) -> TokenStream
.into()
}
+trait FromAttribute: Sized
+{
+ fn from_attribute(attribute: &Attribute) -> Result<Self, syn::Error>;
+}
+
enum TypeItem
{
Struct(ItemStruct),
@@ -126,7 +143,7 @@ impl TypeItem
}
}
- fn component_attribute(&self) -> Option<ComponentAttribute>
+ fn attribute<Attr: FromAttribute>(&self, attr_ident: &str) -> Option<Attr>
{
let item_attrs = match &self {
Self::Struct(struct_item) => &struct_item.attrs,
@@ -134,19 +151,19 @@ impl TypeItem
&Self::Union(union_item) => &union_item.attrs,
};
- let mut component_attr: Option<&Attribute> = None;
+ let mut attr: Option<&Attribute> = None;
for item_attr in item_attrs {
- if component_attr.is_some() {
- panic!("Expected only one component attribute");
+ if attr.is_some() {
+ panic!("Expected only one {} attribute", attr_ident);
}
- if item_attr.path().get_ident()? == "component" {
- component_attr = Some(item_attr);
+ if item_attr.path().get_ident()? == attr_ident {
+ attr = Some(item_attr);
}
}
- Some(ComponentAttribute::from_attribute(component_attr?).unwrap())
+ Some(Attr::from_attribute(attr?).unwrap())
}
}
@@ -186,7 +203,37 @@ struct ComponentAttribute
drop_last: bool,
}
-impl ComponentAttribute
+impl FromAttribute for ComponentAttribute
+{
+ fn from_attribute(attribute: &Attribute) -> Result<Self, syn::Error>
+ {
+ let mut drop_last = false;
+
+ attribute.parse_nested_meta(|meta| {
+ if meta
+ .path
+ .get_ident()
+ .is_some_and(|flag| flag == "drop_last")
+ {
+ drop_last = true;
+
+ return Ok(());
+ }
+
+ Err(meta.error("Unrecognized token"))
+ })?;
+
+ Ok(Self { drop_last })
+ }
+}
+
+#[derive(Debug, Default)]
+struct SoleAttribute
+{
+ drop_last: bool,
+}
+
+impl FromAttribute for SoleAttribute
{
fn from_attribute(attribute: &Attribute) -> Result<Self, syn::Error>
{