|
1 | 1 | use crate::utility::TypeInfoCell;
|
2 | 2 | use crate::{DynamicInfo, NamedField, Reflect, ReflectMut, ReflectRef, TypeInfo, Typed};
|
3 | 3 | use bevy_utils::{Entry, HashMap};
|
| 4 | +use std::borrow::Borrow; |
4 | 5 | use std::fmt::{Debug, Formatter};
|
5 | 6 | use std::{
|
6 | 7 | any::{Any, TypeId},
|
@@ -45,25 +46,91 @@ pub trait Struct: Reflect {
|
45 | 46 | /// `&mut dyn Reflect`.
|
46 | 47 | fn field_mut(&mut self, name: &str) -> Option<&mut dyn Reflect>;
|
47 | 48 |
|
48 |
| - /// Returns a reference to the value of the field with index `index` as a |
49 |
| - /// `&dyn Reflect`. |
50 |
| - fn field_at(&self, index: usize) -> Option<&dyn Reflect>; |
51 |
| - |
52 |
| - /// Returns a mutable reference to the value of the field with index `index` |
53 |
| - /// as a `&mut dyn Reflect`. |
54 |
| - fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect>; |
55 |
| - |
56 |
| - /// Returns the name of the field with index `index`. |
57 |
| - fn name_at(&self, index: usize) -> Option<&str>; |
58 |
| - |
59 |
| - /// Returns the number of fields in the struct. |
60 |
| - fn field_len(&self) -> usize; |
61 |
| - |
62 | 49 | /// Returns an iterator over the values of the struct's fields.
|
63 | 50 | fn iter_fields(&self) -> FieldIter;
|
64 | 51 |
|
65 | 52 | /// Clones the struct into a [`DynamicStruct`].
|
66 | 53 | fn clone_dynamic(&self) -> DynamicStruct;
|
| 54 | + |
| 55 | + /// Returns the number of fields in the struct. |
| 56 | + /// |
| 57 | + /// # Panics |
| 58 | + /// |
| 59 | + /// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not |
| 60 | + /// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions |
| 61 | + /// include [`DynamicStruct`] which uses its own implementation of this method to |
| 62 | + /// prevent the panic. |
| 63 | + fn field_len(&self) -> usize { |
| 64 | + if let TypeInfo::Struct(info) = self.get_type_info() { |
| 65 | + info.field_len() |
| 66 | + } else { |
| 67 | + panic!( |
| 68 | + "tuple `{:?}` is not `TypeInfo::Struct`", |
| 69 | + std::any::type_name::<Self>() |
| 70 | + ); |
| 71 | + } |
| 72 | + } |
| 73 | + |
| 74 | + /// Returns the name of the field with index `index`. |
| 75 | + /// |
| 76 | + /// # Panics |
| 77 | + /// |
| 78 | + /// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not |
| 79 | + /// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions |
| 80 | + /// include [`DynamicStruct`] which uses its own implementation of this method to |
| 81 | + /// prevent the panic. |
| 82 | + fn name_at(&self, index: usize) -> Option<&str> { |
| 83 | + if let TypeInfo::Struct(info) = self.get_type_info() { |
| 84 | + info.field_at(index).map(|field| field.name().borrow()) |
| 85 | + } else { |
| 86 | + panic!( |
| 87 | + "tuple `{:?}` is not `TypeInfo::Struct`", |
| 88 | + std::any::type_name::<Self>() |
| 89 | + ); |
| 90 | + } |
| 91 | + } |
| 92 | + |
| 93 | + /// Returns a reference to the value of the field with index `index` as a |
| 94 | + /// `&dyn Reflect`. |
| 95 | + /// |
| 96 | + /// # Panics |
| 97 | + /// |
| 98 | + /// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not |
| 99 | + /// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions |
| 100 | + /// include [`DynamicStruct`] which uses its own implementation of this method to |
| 101 | + /// prevent the panic. |
| 102 | + fn field_at(&self, index: usize) -> Option<&dyn Reflect> { |
| 103 | + if let TypeInfo::Struct(info) = self.get_type_info() { |
| 104 | + let name = info.field_at(index)?.name(); |
| 105 | + self.field(name) |
| 106 | + } else { |
| 107 | + panic!( |
| 108 | + "tuple `{:?}` is not `TypeInfo::Struct`", |
| 109 | + std::any::type_name::<Self>() |
| 110 | + ); |
| 111 | + } |
| 112 | + } |
| 113 | + |
| 114 | + /// Returns a mutable reference to the value of the field with index `index` |
| 115 | + /// as a `&mut dyn Reflect`. |
| 116 | + /// |
| 117 | + /// # Panics |
| 118 | + /// |
| 119 | + /// Panics if the [`TypeInfo`] returned by [`Reflect::get_type_info()`] is not |
| 120 | + /// [`TypeInfo::Struct`]— which should almost never be the case. Notable exceptions |
| 121 | + /// include [`DynamicStruct`] which uses its own implementation of this method to |
| 122 | + /// prevent the panic. |
| 123 | + fn field_at_mut(&mut self, index: usize) -> Option<&mut dyn Reflect> { |
| 124 | + if let TypeInfo::Struct(info) = self.get_type_info() { |
| 125 | + let name = info.field_at(index)?.name(); |
| 126 | + self.field_mut(name) |
| 127 | + } else { |
| 128 | + panic!( |
| 129 | + "tuple `{:?}` is not `TypeInfo::Struct`", |
| 130 | + std::any::type_name::<Self>() |
| 131 | + ); |
| 132 | + } |
| 133 | + } |
67 | 134 | }
|
68 | 135 |
|
69 | 136 | /// A container for compile-time struct info
|
|
0 commit comments