Trait bevy::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§

source

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.

source

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.

source

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).

source

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).

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<T> GetPath for T
where T: Reflect + ?Sized,