From f18f020d38ab3d0ab6b290159dff34f7431d2fd2 Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 11 Apr 2024 17:50:34 +0200 Subject: fix(ecs-macros): allow for using derive macros via the engine crate --- Cargo.lock | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ ecs-macros/Cargo.toml | 1 + ecs-macros/src/lib.rs | 66 +++++++++++++++++++++++++++++++---- 3 files changed, 156 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b32a48..6a88454 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -137,6 +137,7 @@ dependencies = [ "proc-macro2", "quote", "syn", + "toml", ] [[package]] @@ -153,6 +154,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "fdeflate" version = "0.3.1" @@ -217,6 +224,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "image" version = "0.24.7" @@ -231,6 +244,16 @@ dependencies = [ "png", ] +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "khronos_api" version = "3.1.0" @@ -445,6 +468,35 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -513,6 +565,40 @@ dependencies = [ "once_cell", ] +[[package]] +name = "toml" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.39" @@ -612,6 +698,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winnow" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" +dependencies = [ + "memchr", +] + [[package]] name = "xml-rs" version = "0.8.19" diff --git a/ecs-macros/Cargo.toml b/ecs-macros/Cargo.toml index 792ca34..cf323fc 100644 --- a/ecs-macros/Cargo.toml +++ b/ecs-macros/Cargo.toml @@ -10,4 +10,5 @@ proc-macro = true quote = "1.0.35" syn = { version = "2.0.51", features = ["full"] } proc-macro2 = "1.0.78" +toml = "0.8.12" diff --git a/ecs-macros/src/lib.rs b/ecs-macros/src/lib.rs index 17a9be6..73709e4 100644 --- a/ecs-macros/src/lib.rs +++ b/ecs-macros/src/lib.rs @@ -1,7 +1,34 @@ +use std::path::PathBuf as FsPathBuf; + use proc_macro::TokenStream; use quote::{quote, ToTokens}; use syn::spanned::Spanned; -use syn::{parse, Attribute, Ident, Item, ItemEnum, ItemStruct, ItemUnion}; +use syn::{parse, Attribute, Ident, Item, ItemEnum, ItemStruct, ItemUnion, Path}; +use toml::value::{Table as TomlTable, Value as TomlValue}; + +macro_rules! syn_path { + ($first_segment: ident $(::$segment: ident)*) => { + ::syn::Path { + leading_colon: None, + segments: ::syn::punctuated::Punctuated::from_iter([ + syn_path_segment!($first_segment), + $(syn_path_segment!($segment),)* + ]) + } + }; +} + +macro_rules! syn_path_segment { + ($segment: ident) => { + ::syn::PathSegment { + ident: ::proc_macro2::Ident::new( + stringify!($segment), + ::proc_macro2::Span::call_site(), + ), + arguments: ::syn::PathArguments::None, + } + }; +} #[proc_macro_derive(Component, attributes(component))] pub fn component_derive(input: TokenStream) -> TokenStream @@ -14,8 +41,10 @@ pub fn component_derive(input: TokenStream) -> TokenStream let drop_last = component_attr.drop_last; + let ecs_path = find_engine_ecs_crate_path().unwrap_or_else(|| syn_path!(ecs)); + quote! { - impl ecs::component::Component for #item_ident + impl #ecs_path::component::Component for #item_ident { fn drop_last(&self) -> bool { #drop_last @@ -32,9 +61,9 @@ pub fn component_derive(input: TokenStream) -> TokenStream } } - impl ecs::system::Input for #item_ident {} + impl #ecs_path::system::Input for #item_ident {} - impl ecs::type_name::TypeName for #item_ident + impl #ecs_path::type_name::TypeName for #item_ident { fn type_name(&self) -> &'static str { @@ -52,8 +81,10 @@ pub fn sole_derive(input: TokenStream) -> TokenStream let item_ident = item.ident(); + let ecs_path = find_engine_ecs_crate_path().unwrap_or_else(|| syn_path!(ecs)); + quote! { - impl ecs::sole::Sole for #item_ident + impl #ecs_path::sole::Sole for #item_ident { fn as_any_mut(&mut self) -> &mut dyn std::any::Any { @@ -66,7 +97,7 @@ pub fn sole_derive(input: TokenStream) -> TokenStream } } - impl ecs::type_name::TypeName for #item_ident + impl #ecs_path::type_name::TypeName for #item_ident { fn type_name(&self) -> &'static str { @@ -178,3 +209,26 @@ impl ComponentAttribute Ok(Self { drop_last }) } } + +fn find_engine_ecs_crate_path() -> Option +{ + let cargo_manifest_dir = FsPathBuf::from(std::env::var("CARGO_MANIFEST_DIR").ok()?); + + let crate_manifest = std::fs::read_to_string(cargo_manifest_dir.join("Cargo.toml")) + .ok()? + .parse::() + .expect("Failed to parse crate manifest file"); + + let crate_dependencies = match crate_manifest.get("dependencies")? { + TomlValue::Table(dependencies) => Some(dependencies), + _ => None, + }?; + + crate_dependencies.iter().find_map(|(crate_dep_name, _)| { + if crate_dep_name == "engine" { + return Some(syn_path!(engine::ecs)); + } + + None + }) +} -- cgit v1.2.3-18-g5258