bevy_query_ext/
or_const.rs

1use core::borrow::Borrow;
2use core::marker::PhantomData;
3
4use bevy::ecs::query::{QueryData, ReadOnlyQueryData};
5
6use super::base::{ModQ, ModQuery};
7use super::extensions::AsDeref;
8
9macro_rules! or_const {
10    ($OrConst:ident, $OrConstQ:ident, $AsDerefOrConst: ident, $const_type:ty, $wrapped:literal) => {
11
12        #[derive(Debug)]
13        pub struct $OrConstQ<T, const V: $const_type>(PhantomData<T>);
14
15
16        #[cfg(feature="all_docs")]
17        paste::paste! {
18            #[doc = "When `T` implements `Borrow` for `"]
19            #[doc = stringify!($const_type)]
20            #[doc = "`, this will return that value or the specified value if T has no result.\n"]
21            #[doc = "It's unlikely you'll use this by itself, see [`" $AsDerefOrConst "`] for example of its use."]
22            pub type $OrConst<T, const V: $const_type> = ModQ<$OrConstQ<T, V>>;
23        }
24        #[cfg(not(feature="all_docs"))]
25        pub type $OrConst<T, const V: $const_type> = ModQ<$OrConstQ<T, V>>;
26
27        #[cfg(feature="all_docs")]
28        paste::paste!{
29            #[doc="When `T` implements `Deref` for "]
30            #[doc = stringify!($const_type)]
31            #[doc=", this will return that value or the specified value if T has no result"]
32            #[doc = "## Examples"]
33            #[doc = "```"]
34            #[doc = "# use bevy::prelude::*;"]
35            #[doc = "# use bevy_query_ext::" $AsDerefOrConst ";"]
36            #[doc = "#[derive(Component, Deref)]"]
37            #[doc = "pub struct Wrapped(" $const_type ");\n\n"]
38            #[doc = "fn example(query: Query<" $AsDerefOrConst "<Wrapped, " $wrapped ">>) {"]
39            #[doc = "   let _: " $const_type " = query.get_single().unwrap();"]
40            #[doc = "}"]
41            #[doc = "```"]
42            pub type $AsDerefOrConst<T, const V: $const_type> = $OrConst<AsDeref<T>, V>;
43        }
44
45        #[cfg(not(feature="all_docs"))]
46        pub type $AsDerefOrConst<T, const V: $const_type> = $OrConst<AsDeref<T>, V>;
47
48
49        impl <T: ReadOnlyQueryData, const V: $const_type> ModQuery for $OrConstQ<T, V>
50            where for<'a> <T as QueryData>::Item<'a>: Borrow<$const_type> {
51            type FromQuery = Option<T>;
52            type ModItem<'s> = $const_type;
53
54            fn modify_reference(t: <Self::FromQuery as QueryData>::Item<'_>) -> Self::ModItem<'_> {
55                t.map(|b|*b.borrow()).unwrap_or(V)
56            }
57
58            fn shrink<'wlong: 'wshort, 'wshort>(item: Self::ModItem<'wlong>) -> Self::ModItem<'wshort> {
59                item
60            }
61        }
62    }
63}
64
65or_const!(OrChar, OrCharQ, AsDerefOrChar, char, "'b'");
66or_const!(OrBool, OrBoolQ, AsDerefOrBool, bool, true);
67or_const!(OrIsize, OrIsizeQ, AsDerefOrIsize, isize, 1);
68or_const!(OrUsize, OrUsizeQ, AsDerefOrUsize, usize, 1);
69or_const!(OrI128, OrI128Q, AsDerefOrI128, i128, 1);
70or_const!(OrU128, OrU128Q, AsDerefOrU128, u128, 1);
71or_const!(OrI64, OrI64Q, AsDerefOrI64, i64, 1);
72or_const!(OrU64, OrU64Q, AsDerefOrU64, u64, 1);
73or_const!(OrI32, OrI32Q, AsDerefOrI32, i32, 1);
74or_const!(OrU32, OrU32Q, AsDerefOrU32, u32, 1);
75or_const!(OrI16, OrI16Q, AsDerefOrI16, i16, 1);
76or_const!(OrU16, OrU16Q, AsDerefOrU16, u16, 1);
77or_const!(OrI8, OrI8Q, AsDerefOrI8, i8, 1);
78or_const!(OrU8, OrU8Q, AsDerefOrU8, u8, 1);