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