unlit_ecs/query/
macros.rs1#[macro_export]
60macro_rules! query {
61 (
62 $(#[$meta:meta])*
63 $vis:vis struct $name:ident<$lt:lifetime> {
64 $($body:tt)*
65 }
66 ) => {
67 $crate::__query_fields! {
68 [builder row]
69 [$(#[$meta])*]
70 [$vis $name, $lt]
71 []
72 []
73 []
74 []
75 []
76 [$($body)*]
77 }
78 };
79}
80
81#[doc(hidden)]
82#[macro_export]
83macro_rules! __query_fields {
84 (
86 [$b:ident $r:ident]
87 [$($meta:tt)*]
88 [$vis:vis $name:ident, $lt:lifetime]
89 [$($plan:tt)*]
90 [$($prep:tt)*]
91 [$($bind:tt)*]
92 [$($field:tt)*]
93 [$($init:tt)*]
94 []
95 ) => {
96 $($meta)*
97 $vis struct $name<$lt> {
98 $($field)*
99 }
100
101 impl<$lt> $crate::Query for $name<$lt> {
102 type Item<'r> = $name<'r>;
103 type Plan<'p> = ($($plan)*);
104
105 fn prepare<'p>(
106 $b: &mut $crate::PlanBuilder<'p>,
107 ) -> ::core::option::Option<Self::Plan<'p>> {
108 ::core::option::Option::Some(($($prep)*))
109 }
110
111 fn read<'r, 'p: 'r>(
112 plan: &'r mut Self::Plan<'p>,
113 $r: usize,
114 ) -> Self::Item<'r> {
115 #[expect(
116 unused_variables,
117 reason = "a query whose fields claim nothing still binds their plans"
118 )]
119 let ($($bind)*) = plan;
120 $name { $($init)* }
121 }
122 }
123 };
124
125 (
127 [$b:ident $r:ident]
128 [$($meta:tt)*]
129 [$vis:vis $name:ident, $lt:lifetime]
130 [$($plan:tt)*]
131 [$($prep:tt)*]
132 [$($bind:tt)*]
133 [$($field:tt)*]
134 [$($init:tt)*]
135 [$(#[$fmeta:meta])* $fv:vis $f:ident : Option<&$fl:lifetime mut $t:ty>, $($rest:tt)*]
136 ) => {
137 $crate::__query_fields! {
138 [$b $r]
139 [$($meta)*]
140 [$vis $name, $lt]
141 [$($plan)* ::core::option::Option<$crate::ColMut<'p, $t>>,]
142 [$($prep)* $b.write::<$t>(),]
143 [$($bind)* $f,]
144 [$($field)* $(#[$fmeta])* $fv $f: ::core::option::Option<&$lt mut $t>,]
145 [$($init)* $f: $f.as_mut().map(|column| column.at($r)),]
146 [$($rest)*]
147 }
148 };
149
150 (
152 [$b:ident $r:ident]
153 [$($meta:tt)*]
154 [$vis:vis $name:ident, $lt:lifetime]
155 [$($plan:tt)*]
156 [$($prep:tt)*]
157 [$($bind:tt)*]
158 [$($field:tt)*]
159 [$($init:tt)*]
160 [$(#[$fmeta:meta])* $fv:vis $f:ident : Option<&$fl:lifetime $t:ty>, $($rest:tt)*]
161 ) => {
162 $crate::__query_fields! {
163 [$b $r]
164 [$($meta)*]
165 [$vis $name, $lt]
166 [$($plan)* ::core::option::Option<$crate::Col<'p, $t>>,]
167 [$($prep)* $b.read::<$t>(),]
168 [$($bind)* $f,]
169 [$($field)* $(#[$fmeta])* $fv $f: ::core::option::Option<&$lt $t>,]
170 [$($init)* $f: $f.as_ref().map(|column| column.at($r)),]
171 [$($rest)*]
172 }
173 };
174
175 (
177 [$b:ident $r:ident]
178 [$($meta:tt)*]
179 [$vis:vis $name:ident, $lt:lifetime]
180 [$($plan:tt)*]
181 [$($prep:tt)*]
182 [$($bind:tt)*]
183 [$($field:tt)*]
184 [$($init:tt)*]
185 [$(#[$fmeta:meta])* $fv:vis $f:ident : Has<$t:ty>, $($rest:tt)*]
186 ) => {
187 $crate::__query_fields! {
188 [$b $r]
189 [$($meta)*]
190 [$vis $name, $lt]
191 [$($plan)* bool,]
192 [$($prep)* $b.has::<$t>(),]
193 [$($bind)* $f,]
194 [$($field)* $(#[$fmeta])* $fv $f: bool,]
195 [$($init)* $f: *$f,]
196 [$($rest)*]
197 }
198 };
199
200 (
202 [$b:ident $r:ident]
203 [$($meta:tt)*]
204 [$vis:vis $name:ident, $lt:lifetime]
205 [$($plan:tt)*]
206 [$($prep:tt)*]
207 [$($bind:tt)*]
208 [$($field:tt)*]
209 [$($init:tt)*]
210 [$(#[$fmeta:meta])* $fv:vis $f:ident : Entity, $($rest:tt)*]
211 ) => {
212 $crate::__query_fields! {
213 [$b $r]
214 [$($meta)*]
215 [$vis $name, $lt]
216 [$($plan)* &'p [$crate::Entity],]
217 [$($prep)* $b.entities(),]
218 [$($bind)* $f,]
219 [$($field)* $(#[$fmeta])* $fv $f: $crate::Entity,]
220 [$($init)* $f: $f[$r],]
221 [$($rest)*]
222 }
223 };
224
225 (
227 [$b:ident $r:ident]
228 [$($meta:tt)*]
229 [$vis:vis $name:ident, $lt:lifetime]
230 [$($plan:tt)*]
231 [$($prep:tt)*]
232 [$($bind:tt)*]
233 [$($field:tt)*]
234 [$($init:tt)*]
235 [$(#[$fmeta:meta])* $fv:vis $f:ident : &$fl:lifetime mut $t:ty, $($rest:tt)*]
236 ) => {
237 $crate::__query_fields! {
238 [$b $r]
239 [$($meta)*]
240 [$vis $name, $lt]
241 [$($plan)* $crate::ColMut<'p, $t>,]
242 [$($prep)* $b.write::<$t>()?,]
243 [$($bind)* $f,]
244 [$($field)* $(#[$fmeta])* $fv $f: &$lt mut $t,]
245 [$($init)* $f: $f.at($r),]
246 [$($rest)*]
247 }
248 };
249
250 (
252 [$b:ident $r:ident]
253 [$($meta:tt)*]
254 [$vis:vis $name:ident, $lt:lifetime]
255 [$($plan:tt)*]
256 [$($prep:tt)*]
257 [$($bind:tt)*]
258 [$($field:tt)*]
259 [$($init:tt)*]
260 [$(#[$fmeta:meta])* $fv:vis $f:ident : &$fl:lifetime $t:ty, $($rest:tt)*]
261 ) => {
262 $crate::__query_fields! {
263 [$b $r]
264 [$($meta)*]
265 [$vis $name, $lt]
266 [$($plan)* $crate::Col<'p, $t>,]
267 [$($prep)* $b.read::<$t>()?,]
268 [$($bind)* $f,]
269 [$($field)* $(#[$fmeta])* $fv $f: &$lt $t,]
270 [$($init)* $f: $f.at($r),]
271 [$($rest)*]
272 }
273 };
274
275 (
277 [$b:ident $r:ident]
278 [$($meta:tt)*]
279 [$vis:vis $name:ident, $lt:lifetime]
280 [$($plan:tt)*]
281 [$($prep:tt)*]
282 [$($bind:tt)*]
283 [$($field:tt)*]
284 [$($init:tt)*]
285 [$(#[$fmeta:meta])* $fv:vis $f:ident : $t:ty]
286 ) => {
287 $crate::__query_fields! {
288 [$b $r]
289 [$($meta)*]
290 [$vis $name, $lt]
291 [$($plan)*]
292 [$($prep)*]
293 [$($bind)*]
294 [$($field)*]
295 [$($init)*]
296 [$(#[$fmeta])* $fv $f : $t ,]
297 }
298 };
299
300 (
302 [$b:ident $r:ident]
303 [$($meta:tt)*]
304 [$vis:vis $name:ident, $lt:lifetime]
305 [$($plan:tt)*]
306 [$($prep:tt)*]
307 [$($bind:tt)*]
308 [$($field:tt)*]
309 [$($init:tt)*]
310 [$(#[$fmeta:meta])* $fv:vis $f:ident : $t:ty $(, $($rest:tt)*)?]
311 ) => {
312 ::core::compile_error!(::core::concat!(
313 "field `", ::core::stringify!($f), "` has an unsupported type; ",
314 "a query field is `&'a T`, `&'a mut T`, `Option<&'a T>`, ",
315 "`Option<&'a mut T>`, `Has<T>` or `Entity`",
316 ));
317 };
318}