bevy_reflect/enums/
helpers.rs1use crate::{
2 enums::{Enum, VariantType},
3 utility::reflect_hasher,
4 PartialReflect, ReflectRef,
5};
6use core::{
7 fmt::Debug,
8 hash::{Hash, Hasher},
9};
10
11#[inline(never)]
13pub fn enum_hash(value: &dyn Enum) -> Option<u64> {
14 let mut hasher = reflect_hasher();
15 core::any::Any::type_id(value).hash(&mut hasher);
16 value.variant_name().hash(&mut hasher);
17 value.variant_type().hash(&mut hasher);
18 for field in value.iter_fields() {
19 hasher.write_u64(field.value().reflect_hash()?);
20 }
21 Some(hasher.finish())
22}
23
24#[inline(never)]
33pub fn enum_partial_eq(a: &dyn Enum, b: &dyn PartialReflect) -> Option<bool> {
34 let ReflectRef::Enum(b) = b.reflect_ref() else {
36 return Some(false);
37 };
38
39 if a.variant_name() != b.variant_name() {
41 return Some(false);
42 }
43
44 if !a.is_variant(b.variant_type()) {
46 return Some(false);
47 }
48
49 match a.variant_type() {
50 VariantType::Struct => {
51 if a.field_len() != b.field_len() {
52 return Some(false);
53 }
54 for field in a.iter_fields() {
56 let field_name = field.name().unwrap();
57 if let Some(field_value) = b.field(field_name) {
58 if let Some(false) | None = field_value.reflect_partial_eq(field.value()) {
59 return Some(false);
61 }
62 } else {
63 return Some(false);
65 }
66 }
67 Some(true)
68 }
69 VariantType::Tuple => {
70 if a.field_len() != b.field_len() {
71 return Some(false);
72 }
73 for (i, field) in a.iter_fields().enumerate() {
75 if let Some(field_value) = b.field_at(i) {
76 if let Some(false) | None = field_value.reflect_partial_eq(field.value()) {
77 return Some(false);
79 }
80 } else {
81 return Some(false);
83 }
84 }
85 Some(true)
86 }
87 _ => Some(true),
88 }
89}
90
91#[inline(never)]
98pub fn enum_partial_cmp(a: &dyn Enum, b: &dyn PartialReflect) -> Option<::core::cmp::Ordering> {
99 let ReflectRef::Enum(b) = b.reflect_ref() else {
101 return None;
102 };
103
104 if a.variant_name() != b.variant_name() {
106 return None;
111 }
112
113 if !a.is_variant(b.variant_type()) {
115 return None;
116 }
117
118 match a.variant_type() {
119 VariantType::Struct => {
120 if a.field_len() != b.field_len() {
121 return None;
122 }
123 crate::structs::partial_cmp_by_field_names(
124 a.field_len(),
125 |i| a.name_at(i),
126 |i| a.field_at(i),
127 |i| b.name_at(i),
128 |i| b.field_at(i),
129 |name| b.field(name),
130 )
131 }
132 VariantType::Tuple => {
133 if a.field_len() != b.field_len() {
134 return None;
135 }
136 for (i, field) in a.iter_fields().enumerate() {
137 if let Some(field_value) = b.field_at(i) {
138 match field.value().reflect_partial_cmp(field_value) {
139 None => return None,
140 Some(core::cmp::Ordering::Equal) => continue,
141 Some(ord) => return Some(ord),
142 }
143 }
144 return None;
145 }
146 Some(core::cmp::Ordering::Equal)
147 }
148 _ => Some(core::cmp::Ordering::Equal),
149 }
150}
151
152#[inline]
174pub fn enum_debug(dyn_enum: &dyn Enum, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
175 match dyn_enum.variant_type() {
176 VariantType::Unit => f.write_str(dyn_enum.variant_name()),
177 VariantType::Tuple => {
178 let mut debug = f.debug_tuple(dyn_enum.variant_name());
179 for field in dyn_enum.iter_fields() {
180 debug.field(&field.value() as &dyn Debug);
181 }
182 debug.finish()
183 }
184 VariantType::Struct => {
185 let mut debug = f.debug_struct(dyn_enum.variant_name());
186 for field in dyn_enum.iter_fields() {
187 debug.field(field.name().unwrap(), &field.value() as &dyn Debug);
188 }
189 debug.finish()
190 }
191 }
192}