1use crate::{std_traits::ReflectDefault, ReflectDeserialize, ReflectSerialize};
2use assert_type_match::assert_type_match;
3use bevy_reflect_derive::{impl_reflect, impl_reflect_opaque};
4use glam::*;
5
6macro_rules! reflect_enum {
8 ($(#[$meta:meta])* enum $ident:ident { $($ty:tt)* } ) => {
9 impl_reflect!($(#[$meta])* enum $ident { $($ty)* });
10
11 #[assert_type_match($ident, test_only)]
12 #[expect(
13 clippy::upper_case_acronyms,
14 reason = "The variants used are not acronyms."
15 )]
16 enum $ident { $($ty)* }
17 };
18}
19
20impl_reflect!(
21 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
22 #[type_path = "glam"]
23 struct IVec2 {
24 x: i32,
25 y: i32,
26 }
27);
28impl_reflect!(
29 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
30 #[type_path = "glam"]
31 struct IVec3 {
32 x: i32,
33 y: i32,
34 z: i32,
35 }
36);
37impl_reflect!(
38 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
39 #[type_path = "glam"]
40 struct IVec4 {
41 x: i32,
42 y: i32,
43 z: i32,
44 w: i32,
45 }
46);
47
48impl_reflect!(
49 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
50 #[type_path = "glam"]
51 struct I8Vec2 {
52 x: i8,
53 y: i8,
54 }
55);
56
57impl_reflect!(
58 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
59 #[type_path = "glam"]
60 struct I8Vec3 {
61 x: i8,
62 y: i8,
63 z: i8,
64 }
65);
66
67impl_reflect!(
68 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
69 #[type_path = "glam"]
70 struct I8Vec4 {
71 x: i8,
72 y: i8,
73 z: i8,
74 w: i8,
75 }
76);
77
78impl_reflect!(
79 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
80 #[type_path = "glam"]
81 struct I16Vec2 {
82 x: i16,
83 y: i16,
84 }
85);
86
87impl_reflect!(
88 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
89 #[type_path = "glam"]
90 struct I16Vec3 {
91 x: i16,
92 y: i16,
93 z: i16,
94 }
95);
96
97impl_reflect!(
98 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
99 #[type_path = "glam"]
100 struct I16Vec4 {
101 x: i16,
102 y: i16,
103 z: i16,
104 w: i16,
105 }
106);
107
108impl_reflect!(
109 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
110 #[type_path = "glam"]
111 struct I64Vec2 {
112 x: i64,
113 y: i64,
114 }
115);
116
117impl_reflect!(
118 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
119 #[type_path = "glam"]
120 struct I64Vec3 {
121 x: i64,
122 y: i64,
123 z: i64,
124 }
125);
126
127impl_reflect!(
128 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
129 #[type_path = "glam"]
130 struct I64Vec4 {
131 x: i64,
132 y: i64,
133 z: i64,
134 w: i64,
135 }
136);
137
138impl_reflect!(
139 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
140 #[type_path = "glam"]
141 struct UVec2 {
142 x: u32,
143 y: u32,
144 }
145);
146impl_reflect!(
147 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
148 #[type_path = "glam"]
149 struct UVec3 {
150 x: u32,
151 y: u32,
152 z: u32,
153 }
154);
155impl_reflect!(
156 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
157 #[type_path = "glam"]
158 struct UVec4 {
159 x: u32,
160 y: u32,
161 z: u32,
162 w: u32,
163 }
164);
165
166impl_reflect!(
167 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
168 #[type_path = "glam"]
169 struct U8Vec2 {
170 x: u8,
171 y: u8,
172 }
173);
174impl_reflect!(
175 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
176 #[type_path = "glam"]
177 struct U8Vec3 {
178 x: u8,
179 y: u8,
180 z: u8,
181 }
182);
183impl_reflect!(
184 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
185 #[type_path = "glam"]
186 struct U8Vec4 {
187 x: u8,
188 y: u8,
189 z: u8,
190 w: u8,
191 }
192);
193
194impl_reflect!(
195 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
196 #[type_path = "glam"]
197 struct U16Vec2 {
198 x: u16,
199 y: u16,
200 }
201);
202impl_reflect!(
203 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
204 #[type_path = "glam"]
205 struct U16Vec3 {
206 x: u16,
207 y: u16,
208 z: u16,
209 }
210);
211impl_reflect!(
212 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
213 #[type_path = "glam"]
214 struct U16Vec4 {
215 x: u16,
216 y: u16,
217 z: u16,
218 w: u16,
219 }
220);
221
222impl_reflect!(
223 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
224 #[type_path = "glam"]
225 struct U64Vec2 {
226 x: u64,
227 y: u64,
228 }
229);
230impl_reflect!(
231 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
232 #[type_path = "glam"]
233 struct U64Vec3 {
234 x: u64,
235 y: u64,
236 z: u64,
237 }
238);
239impl_reflect!(
240 #[reflect(Clone, Debug, Hash, PartialEq, Default, Deserialize, Serialize)]
241 #[type_path = "glam"]
242 struct U64Vec4 {
243 x: u64,
244 y: u64,
245 z: u64,
246 w: u64,
247 }
248);
249
250impl_reflect!(
251 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
252 #[type_path = "glam"]
253 struct Vec2 {
254 x: f32,
255 y: f32,
256 }
257);
258impl_reflect!(
259 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
260 #[type_path = "glam"]
261 struct Vec3 {
262 x: f32,
263 y: f32,
264 z: f32,
265 }
266);
267impl_reflect!(
268 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
269 #[type_path = "glam"]
270 struct Vec3A {
271 x: f32,
272 y: f32,
273 z: f32,
274 }
275);
276impl_reflect!(
277 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
278 #[type_path = "glam"]
279 struct Vec4 {
280 x: f32,
281 y: f32,
282 z: f32,
283 w: f32,
284 }
285);
286
287impl_reflect!(
288 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
289 #[type_path = "glam"]
290 struct BVec2 {
291 x: bool,
292 y: bool,
293 }
294);
295impl_reflect!(
296 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
297 #[type_path = "glam"]
298 struct BVec3 {
299 x: bool,
300 y: bool,
301 z: bool,
302 }
303);
304impl_reflect!(
305 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
306 #[type_path = "glam"]
307 struct BVec4 {
308 x: bool,
309 y: bool,
310 z: bool,
311 w: bool,
312 }
313);
314
315impl_reflect!(
316 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
317 #[type_path = "glam"]
318 struct DVec2 {
319 x: f64,
320 y: f64,
321 }
322);
323impl_reflect!(
324 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
325 #[type_path = "glam"]
326 struct DVec3 {
327 x: f64,
328 y: f64,
329 z: f64,
330 }
331);
332impl_reflect!(
333 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
334 #[type_path = "glam"]
335 struct DVec4 {
336 x: f64,
337 y: f64,
338 z: f64,
339 w: f64,
340 }
341);
342
343impl_reflect!(
344 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
345 #[type_path = "glam"]
346 struct Mat2 {
347 x_axis: Vec2,
348 y_axis: Vec2,
349 }
350);
351impl_reflect!(
352 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
353 #[type_path = "glam"]
354 struct Mat3 {
355 x_axis: Vec3,
356 y_axis: Vec3,
357 z_axis: Vec3,
358 }
359);
360impl_reflect!(
361 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
362 #[type_path = "glam"]
363 struct Mat3A {
364 x_axis: Vec3A,
365 y_axis: Vec3A,
366 z_axis: Vec3A,
367 }
368);
369impl_reflect!(
370 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
371 #[type_path = "glam"]
372 struct Mat4 {
373 x_axis: Vec4,
374 y_axis: Vec4,
375 z_axis: Vec4,
376 w_axis: Vec4,
377 }
378);
379
380impl_reflect!(
381 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
382 #[type_path = "glam"]
383 struct DMat2 {
384 x_axis: DVec2,
385 y_axis: DVec2,
386 }
387);
388impl_reflect!(
389 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
390 #[type_path = "glam"]
391 struct DMat3 {
392 x_axis: DVec3,
393 y_axis: DVec3,
394 z_axis: DVec3,
395 }
396);
397impl_reflect!(
398 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
399 #[type_path = "glam"]
400 struct DMat4 {
401 x_axis: DVec4,
402 y_axis: DVec4,
403 z_axis: DVec4,
404 w_axis: DVec4,
405 }
406);
407
408impl_reflect!(
409 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
410 #[type_path = "glam"]
411 struct Affine2 {
412 matrix2: Mat2,
413 translation: Vec2,
414 }
415);
416impl_reflect!(
417 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
418 #[type_path = "glam"]
419 struct Affine3 {
420 matrix3: Mat3,
421 translation: Vec3,
422 }
423);
424impl_reflect!(
425 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
426 #[type_path = "glam"]
427 struct Affine3A {
428 matrix3: Mat3A,
429 translation: Vec3A,
430 }
431);
432
433impl_reflect!(
434 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
435 #[type_path = "glam"]
436 struct DAffine2 {
437 matrix2: DMat2,
438 translation: DVec2,
439 }
440);
441impl_reflect!(
442 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
443 #[type_path = "glam"]
444 struct DAffine3 {
445 matrix3: DMat3,
446 translation: DVec3,
447 }
448);
449
450impl_reflect!(
451 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
452 #[type_path = "glam"]
453 struct Quat {
454 x: f32,
455 y: f32,
456 z: f32,
457 w: f32,
458 }
459);
460impl_reflect!(
461 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
462 #[type_path = "glam"]
463 struct DQuat {
464 x: f64,
465 y: f64,
466 z: f64,
467 w: f64,
468 }
469);
470
471reflect_enum!(
472 #[reflect(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
473 #[type_path = "glam"]
474 enum EulerRot {
475 ZYX,
476 ZXY,
477 YXZ,
478 YZX,
479 XYZ,
480 XZY,
481 ZYZ,
482 ZXZ,
483 YXY,
484 YZY,
485 XYX,
486 XZX,
487 ZYXEx,
488 ZXYEx,
489 YXZEx,
490 YZXEx,
491 XYZEx,
492 XZYEx,
493 ZYZEx,
494 ZXZEx,
495 YXYEx,
496 YZYEx,
497 XYXEx,
498 XZXEx,
499 }
500);
501
502impl_reflect_opaque!(::glam::BVec3A(
503 Clone,
504 Debug,
505 Default,
506 Deserialize,
507 Serialize
508));
509impl_reflect_opaque!(::glam::BVec4A(
510 Clone,
511 Debug,
512 Default,
513 Deserialize,
514 Serialize
515));
516
517#[cfg(test)]
518mod tests {
519 use alloc::{format, string::String};
520 use ron::{
521 ser::{to_string_pretty, PrettyConfig},
522 Deserializer,
523 };
524 use serde::de::DeserializeSeed;
525 use static_assertions::assert_impl_all;
526
527 use crate::{
528 enums::Enum,
529 prelude::*,
530 serde::{ReflectDeserializer, ReflectSerializer},
531 GetTypeRegistration, TypeRegistry,
532 };
533
534 use super::*;
535
536 assert_impl_all!(EulerRot: Enum);
537
538 #[test]
539 fn euler_rot_serialization() {
540 let v = EulerRot::YXZ;
541
542 let mut registry = TypeRegistry::default();
543 registry.register::<EulerRot>();
544
545 let ser = ReflectSerializer::new(&v, ®istry);
546
547 let config = PrettyConfig::default()
548 .new_line(String::from("\n"))
549 .indentor(String::from(" "));
550 let output = to_string_pretty(&ser, config).unwrap();
551 let expected = r#"
552{
553 "glam::EulerRot": YXZ,
554}"#;
555
556 assert_eq!(expected, format!("\n{output}"));
557 }
558
559 #[test]
560 fn euler_rot_deserialization() {
561 let data = r#"
562{
563 "glam::EulerRot": XZY,
564}"#;
565
566 let mut registry = TypeRegistry::default();
567 registry.add_registration(EulerRot::get_type_registration());
568
569 let de = ReflectDeserializer::new(®istry);
570
571 let mut deserializer =
572 Deserializer::from_str(data).expect("Failed to acquire deserializer");
573
574 let dynamic_struct = de
575 .deserialize(&mut deserializer)
576 .expect("Failed to deserialize");
577
578 let mut result = EulerRot::default();
579
580 result.apply(dynamic_struct.as_partial_reflect());
581
582 assert_eq!(result, EulerRot::XZY);
583 }
584}