Skip to main content

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