hecs_macros/
lib.rs

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