Skip to main content

bevy_reflect/impls/core/
option.rs

1#![expect(
2    unused_qualifications,
3    reason = "the macro uses `MyEnum::Variant` which is generally unnecessary for `Option`"
4)]
5
6use bevy_reflect_derive::impl_reflect;
7
8impl_reflect! {
9    #[type_path = "core::option"]
10    enum Option<T> {
11        None,
12        Some(T),
13    }
14}
15
16#[cfg(test)]
17mod tests {
18    use crate::{
19        enums::{Enum, VariantInfo, VariantType},
20        FromReflect, PartialReflect, TypeInfo, Typed,
21    };
22    use bevy_reflect_derive::Reflect;
23    use static_assertions::assert_impl_all;
24
25    #[test]
26    fn should_partial_eq_option() {
27        let a: &dyn PartialReflect = &Some(123);
28        let b: &dyn PartialReflect = &Some(123);
29        assert_eq!(Some(true), a.reflect_partial_eq(b));
30    }
31
32    #[test]
33    fn option_should_impl_enum() {
34        assert_impl_all!(Option<()>: Enum);
35
36        let mut value = Some(123usize);
37
38        assert!(value
39            .reflect_partial_eq(&Some(123usize))
40            .unwrap_or_default());
41        assert!(!value
42            .reflect_partial_eq(&Some(321usize))
43            .unwrap_or_default());
44
45        assert_eq!("Some", value.variant_name());
46        assert_eq!("core::option::Option<usize>::Some", value.variant_path());
47
48        if value.is_variant(VariantType::Tuple) {
49            if let Some(field) = value
50                .field_at_mut(0)
51                .and_then(|field| field.try_downcast_mut::<usize>())
52            {
53                *field = 321;
54            }
55        } else {
56            panic!("expected `VariantType::Tuple`");
57        }
58
59        assert_eq!(Some(321), value);
60    }
61
62    #[test]
63    fn option_should_from_reflect() {
64        #[derive(Reflect, PartialEq, Debug)]
65        struct Foo(usize);
66
67        let expected = Some(Foo(123));
68        let output = <Option<Foo> as FromReflect>::from_reflect(&expected).unwrap();
69
70        assert_eq!(expected, output);
71    }
72
73    #[test]
74    fn option_should_apply() {
75        #[derive(Reflect, PartialEq, Debug)]
76        struct Foo(usize);
77
78        // === None on None === //
79        let patch = None::<Foo>;
80        let mut value = None::<Foo>;
81        PartialReflect::apply(&mut value, &patch);
82
83        assert_eq!(patch, value, "None apply onto None");
84
85        // === Some on None === //
86        let patch = Some(Foo(123));
87        let mut value = None::<Foo>;
88        PartialReflect::apply(&mut value, &patch);
89
90        assert_eq!(patch, value, "Some apply onto None");
91
92        // === None on Some === //
93        let patch = None::<Foo>;
94        let mut value = Some(Foo(321));
95        PartialReflect::apply(&mut value, &patch);
96
97        assert_eq!(patch, value, "None apply onto Some");
98
99        // === Some on Some === //
100        let patch = Some(Foo(123));
101        let mut value = Some(Foo(321));
102        PartialReflect::apply(&mut value, &patch);
103
104        assert_eq!(patch, value, "Some apply onto Some");
105    }
106
107    #[test]
108    fn option_should_impl_typed() {
109        assert_impl_all!(Option<()>: Typed);
110
111        type MyOption = Option<i32>;
112        let info = MyOption::type_info();
113        if let TypeInfo::Enum(info) = info {
114            assert_eq!(
115                "None",
116                info.variant_at(0).unwrap().name(),
117                "Expected `None` to be variant at index `0`"
118            );
119            assert_eq!(
120                "Some",
121                info.variant_at(1).unwrap().name(),
122                "Expected `Some` to be variant at index `1`"
123            );
124            assert_eq!("Some", info.variant("Some").unwrap().name());
125            if let VariantInfo::Tuple(variant) = info.variant("Some").unwrap() {
126                assert!(
127                    variant.field_at(0).unwrap().is::<i32>(),
128                    "Expected `Some` variant to contain `i32`"
129                );
130                assert!(
131                    variant.field_at(1).is_none(),
132                    "Expected `Some` variant to only contain 1 field"
133                );
134            } else {
135                panic!("Expected `VariantInfo::Tuple`");
136            }
137        } else {
138            panic!("Expected `TypeInfo::Enum`");
139        }
140    }
141}