hecs_macros/lib.rs
1extern crate proc_macro;
2
3mod bundle;
4mod bundle_clone;
5mod query;
6
7pub(crate) mod common;
8
9use proc_macro::TokenStream;
10use syn::{parse_macro_input, DeriveInput};
11
12/// Implement `Bundle` for a struct
13///
14/// Bundles can be passed directly to `World::spawn` and `World::insert`, and obtained from
15/// `World::remove`. Can be convenient when combined with other derives like `serde::Deserialize`.
16///
17/// # Example
18/// ```
19/// # use hecs::*;
20/// #[derive(Bundle)]
21/// struct Foo {
22/// x: i32,
23/// y: char,
24/// }
25///
26/// let mut world = World::new();
27/// let e = world.spawn(Foo { x: 42, y: 'a' });
28/// assert_eq!(*world.get::<&i32>(e).unwrap(), 42);
29/// ```
30#[proc_macro_derive(Bundle)]
31pub fn derive_bundle(input: TokenStream) -> TokenStream {
32 let input = parse_macro_input!(input as DeriveInput);
33 match bundle::derive(input) {
34 Ok(ts) => ts,
35 Err(e) => e.to_compile_error(),
36 }
37 .into()
38}
39
40/// Implement `DynamicBundleClone` for a struct.
41///
42/// This is an extension macro for bundles which allow them to be cloned, and
43/// subsequently used in `EntityBuilderClone::add_bundle`.
44///
45/// Requires that all fields of the struct implement [`Clone`].
46///
47/// The trait Bundle must also be implemented to be able to be used in
48/// entity builder.
49#[proc_macro_derive(DynamicBundleClone)]
50pub fn derive_dynamic_bundle_clone(input: TokenStream) -> TokenStream {
51 let input = parse_macro_input!(input as DeriveInput);
52 match bundle_clone::derive(input) {
53 Ok(ts) => ts,
54 Err(e) => e.to_compile_error(),
55 }
56 .into()
57}
58
59/// Implement `Query` for a struct or enum.
60///
61/// Queries can be passed to the type parameter of `World::query`. They must have exactly
62/// one lifetime parameter, and all of their fields must be queries (e.g. references) using that
63/// lifetime.
64///
65/// For enum queries, the result will always be the first variant that matches the entity.
66/// Unit variants and variants without any fields will always match an entity.
67///
68/// # Example
69/// ```
70/// # use hecs::*;
71/// #[derive(Query, Debug, PartialEq)]
72/// struct Foo<'a> {
73/// x: &'a i32,
74/// y: &'a mut bool,
75/// }
76///
77/// let mut world = World::new();
78/// let e = world.spawn((42, false));
79/// assert_eq!(
80/// world.query_one_mut::<Foo>(e).unwrap(),
81/// Foo {
82/// x: &42,
83/// y: &mut false
84/// }
85/// );
86/// ```
87#[proc_macro_derive(Query)]
88pub fn derive_query(input: TokenStream) -> TokenStream {
89 let input = parse_macro_input!(input as DeriveInput);
90 match query::derive(input) {
91 Ok(ts) => ts,
92 Err(e) => e.to_compile_error(),
93 }
94 .into()
95}