Trait bevy_internal::reflect::GetPath
source · pub trait GetPath: Reflect {
// Provided methods
fn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>
) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>> { ... }
fn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>> { ... }
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>
where T: Reflect { ... }
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>
where T: Reflect { ... }
}
Expand description
A trait which allows nested Reflect
values to be retrieved with path strings.
Using these functions repeatedly with the same string requires parsing the string every time.
To avoid this cost, it’s recommended to construct a ParsedPath
instead.
Syntax
Structs
Field paths for Struct
elements use the standard Rust field access syntax of
dot and field name: .field_name
.
Additionally, struct fields may be accessed by their index within the struct’s definition.
This is accomplished by using the hash symbol (#
) in place of the standard dot: #0
.
Accessing a struct’s field by index can speed up fetches at runtime due to the removed need for string matching. And while this can be more performant, it’s best to keep in mind the tradeoffs when utilizing such optimizations. For example, this can result in fairly fragile code as the string paths will need to be kept in sync with the struct definitions since the order of fields could be easily changed. Because of this, storing these kinds of paths in persistent storage (i.e. game assets) is strongly discouraged.
Note that a leading dot (.
) or hash (#
) token is implied for the first item in a path,
and may therefore be omitted.
Example
#[derive(Reflect)]
struct MyStruct {
value: u32
}
let my_struct = MyStruct { value: 123 };
// Access via field name
assert_eq!(my_struct.path::<u32>(".value").unwrap(), &123);
// Access via field index
assert_eq!(my_struct.path::<u32>("#0").unwrap(), &123);
Tuples and Tuple Structs
Tuple
and TupleStruct
elements also follow a conventional Rust syntax.
Fields are accessed with a dot and the field index: .0
.
Note that a leading dot (.
) token is implied for the first item in a path,
and may therefore be omitted.
Example
#[derive(Reflect)]
struct MyTupleStruct(u32);
let my_tuple_struct = MyTupleStruct(123);
assert_eq!(my_tuple_struct.path::<u32>(".0").unwrap(), &123);
Lists and Arrays
List
and Array
elements are accessed with brackets: [0]
.
Example
let my_list: Vec<u32> = vec![1, 2, 3];
assert_eq!(my_list.path::<u32>("[2]").unwrap(), &3);
Enums
Pathing for Enum
elements works a bit differently than in normal Rust.
Usually, you would need to pattern match an enum, branching off on the desired variants.
Paths used by this trait do not have any pattern matching capabilities;
instead, they assume the variant is already known ahead of time.
The syntax used, therefore, depends on the variant being accessed:
- Struct variants use the struct syntax (outlined above)
- Tuple variants use the tuple syntax (outlined above)
- Unit variants have no fields to access
If the variant cannot be known ahead of time, the path will need to be split up and proper enum pattern matching will need to be handled manually.
Example
#[derive(Reflect)]
enum MyEnum {
Unit,
Tuple(bool),
Struct {
value: u32
}
}
let tuple_variant = MyEnum::Tuple(true);
assert_eq!(tuple_variant.path::<bool>(".0").unwrap(), &true);
let struct_variant = MyEnum::Struct { value: 123 };
// Access via field name
assert_eq!(struct_variant.path::<u32>(".value").unwrap(), &123);
// Access via field index
assert_eq!(struct_variant.path::<u32>("#0").unwrap(), &123);
// Error: Expected struct variant
assert!(matches!(tuple_variant.path::<u32>(".value"), Err(_)));
Chaining
Using the aforementioned syntax, path items may be chained one after another to create a full path to a nested element.
Example
#[derive(Reflect)]
struct MyStruct {
value: Vec<Option<u32>>
}
let my_struct = MyStruct {
value: vec![None, None, Some(123)],
};
assert_eq!(
my_struct.path::<u32>(".value[2].0").unwrap(),
&123,
);
Provided Methods§
sourcefn reflect_path<'p>(
&self,
path: impl ReflectPath<'p>
) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>
fn reflect_path<'p>( &self, path: impl ReflectPath<'p> ) -> Result<&(dyn Reflect + 'static), ReflectPathError<'p>>
Returns a reference to the value specified by path
.
To retrieve a statically typed reference, use
path
.
sourcefn reflect_path_mut<'p>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>
fn reflect_path_mut<'p>( &mut self, path: impl ReflectPath<'p> ) -> Result<&mut (dyn Reflect + 'static), ReflectPathError<'p>>
Returns a mutable reference to the value specified by path
.
To retrieve a statically typed mutable reference, use
path_mut
.
sourcefn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
fn path<'p, T>(
&self,
path: impl ReflectPath<'p>
) -> Result<&T, ReflectPathError<'p>>where
T: Reflect,
Returns a statically typed reference to the value specified by path
.
This will automatically handle downcasting to type T
.
The downcast will fail if this value is not of type T
(which may be the case when using dynamic types like DynamicStruct
).
sourcefn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
fn path_mut<'p, T>(
&mut self,
path: impl ReflectPath<'p>
) -> Result<&mut T, ReflectPathError<'p>>where
T: Reflect,
Returns a statically typed mutable reference to the value specified by path
.
This will automatically handle downcasting to type T
.
The downcast will fail if this value is not of type T
(which may be the case when using dynamic types like DynamicStruct
).