Skip to content

Commit 486994d

Browse files
committed
Add the Enum trait to reflect enum types
1 parent 3529dd6 commit 486994d

File tree

5 files changed

+64
-1
lines changed

5 files changed

+64
-1
lines changed

crates/bevy_reflect/src/enum_trait.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use crate::{Reflect, Struct, Tuple};
2+
3+
pub trait Enum: Reflect {
4+
fn variant(&self) -> EnumVariant<'_>;
5+
fn variant_mut(&mut self) -> EnumVariantMut<'_>;
6+
fn variant_info(&self) -> VariantInfo<'_>;
7+
fn iter_variants_info(&self) -> VariantInfoIter<'_>;
8+
fn get_index_name(&self, index: usize) -> Option<&str>;
9+
fn get_index_from_name(&self, name: &str) -> Option<usize>;
10+
}
11+
pub struct VariantInfo<'a> {
12+
pub index: usize,
13+
pub name: &'a str,
14+
}
15+
pub struct VariantInfoIter<'a> {
16+
pub(crate) value: &'a dyn Enum,
17+
pub(crate) index: usize,
18+
pub(crate) len: usize,
19+
}
20+
impl<'a> Iterator for VariantInfoIter<'a> {
21+
type Item = VariantInfo<'a>;
22+
23+
fn next(&mut self) -> Option<Self::Item> {
24+
if self.index == self.len {
25+
return None;
26+
}
27+
let item = VariantInfo {
28+
index: self.index,
29+
name: self.value.get_index_name(self.index).unwrap(),
30+
};
31+
self.index += 1;
32+
Some(item)
33+
}
34+
35+
fn size_hint(&self) -> (usize, Option<usize>) {
36+
let size = self.len - self.index;
37+
(size, Some(size))
38+
}
39+
}
40+
impl<'a> ExactSizeIterator for VariantInfoIter<'a> {}
41+
42+
pub enum EnumVariant<'a> {
43+
Unit,
44+
NewType(&'a dyn Reflect),
45+
Tuple(&'a dyn Tuple),
46+
Struct(&'a dyn Struct),
47+
}
48+
pub enum EnumVariantMut<'a> {
49+
Unit,
50+
NewType(&'a mut dyn Reflect),
51+
Tuple(&'a mut dyn Tuple),
52+
Struct(&'a mut dyn Struct),
53+
}

crates/bevy_reflect/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod enum_trait;
12
mod list;
23
mod map;
34
mod path;
@@ -41,6 +42,7 @@ pub mod prelude {
4142
};
4243
}
4344

45+
pub use enum_trait::*;
4446
pub use impls::*;
4547
pub use list::*;
4648
pub use map::*;

crates/bevy_reflect/src/reflect.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{serde::Serializable, List, Map, Struct, Tuple, TupleStruct};
1+
use crate::{serde::Serializable, Enum, List, Map, Struct, Tuple, TupleStruct};
22
use std::{any::Any, fmt::Debug};
33

44
pub use bevy_utils::AHasher as ReflectHasher;
@@ -9,6 +9,7 @@ pub enum ReflectRef<'a> {
99
Tuple(&'a dyn Tuple),
1010
List(&'a dyn List),
1111
Map(&'a dyn Map),
12+
Enum(&'a dyn Enum),
1213
Value(&'a dyn Reflect),
1314
}
1415

@@ -18,6 +19,7 @@ pub enum ReflectMut<'a> {
1819
Tuple(&'a mut dyn Tuple),
1920
List(&'a mut dyn List),
2021
Map(&'a mut dyn Map),
22+
Enum(&'a mut dyn Enum),
2123
Value(&'a mut dyn Reflect),
2224
}
2325

crates/bevy_reflect/src/serde/ser.rs

+3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ impl<'a> Serialize for ReflectSerializer<'a> {
7777
value,
7878
}
7979
.serialize(serializer),
80+
ReflectRef::Enum(_value) => {
81+
todo!()
82+
}
8083
}
8184
}
8285
}

examples/reflection/reflection_types.rs

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ fn setup() {
7575
// operations on your type, allowing you to interact with fields via their indices. Tuple is automatically
7676
// implemented for tuples of arity 12 or less.
7777
ReflectRef::Tuple(_) => {}
78+
// `Enum` is a trait automatically implemented for enums that derive Reflect. This trait allows you
79+
// to interact list possible variants and interact with the currently active one
80+
ReflectRef::Enum(_) => {}
7881
// `List` is a special trait that can be manually implemented (instead of deriving Reflect). This exposes "list"
7982
// operations on your type, such as indexing and insertion. List is automatically implemented for relevant core
8083
// types like Vec<T>

0 commit comments

Comments
 (0)