Make reflect_partial_eq return more accurate results (#5210)

# Objective

Closes #5204

## Solution

- Followed @nicopap suggestion on https://github.com/bevyengine/bevy/pull/4761#discussion_r903982224

## Changelog

- [x] Updated [struct_trait](dfe9690052/crates/bevy_reflect/src/struct_trait.rs (L455-L457)), [tuple_struct](dfe9690052/crates/bevy_reflect/src/tuple_struct.rs (L366-L368)), [tuple](dfe9690052/crates/bevy_reflect/src/tuple.rs (L386)), [array](dfe9690052/crates/bevy_reflect/src/array.rs (L335-L337)), [list](dfe9690052/crates/bevy_reflect/src/list.rs (L309-L311)) and [map](dfe9690052/crates/bevy_reflect/src/map.rs (L361-L363)) to return `None` when comparison couldn't be performed.
- [x] Updated docs comments to reflect above changes.
This commit is contained in:
Afonso Lage 2022-07-05 17:41:54 +00:00
parent a249e95693
commit 40982cd0a2
6 changed files with 30 additions and 13 deletions

View file

@ -327,13 +327,16 @@ pub fn array_apply<A: Array>(array: &mut A, reflect: &dyn Reflect) {
/// Compares two [arrays](Array) (one concrete and one reflected) to see if they
/// are equal.
///
/// Returns [`None`] if the comparison couldn't even be performed.
#[inline]
pub fn array_partial_eq<A: Array>(array: &A, reflect: &dyn Reflect) -> Option<bool> {
match reflect.reflect_ref() {
ReflectRef::Array(reflect_array) if reflect_array.len() == array.len() => {
for (a, b) in array.iter().zip(reflect_array.iter()) {
if let Some(false) | None = a.reflect_partial_eq(b) {
return Some(false);
let eq_result = a.reflect_partial_eq(b);
if let failed @ (Some(false) | None) = eq_result {
return failed;
}
}
}

View file

@ -293,6 +293,8 @@ pub fn list_apply<L: List>(a: &mut L, b: &dyn Reflect) {
/// - `b` is a list;
/// - `b` is the same length as `a`;
/// - [`Reflect::reflect_partial_eq`] returns `Some(true)` for pairwise elements of `a` and `b`.
///
/// Returns [`None`] if the comparison couldn't even be performed.
#[inline]
pub fn list_partial_eq<L: List>(a: &L, b: &dyn Reflect) -> Option<bool> {
let list = if let ReflectRef::List(list) = b.reflect_ref() {
@ -306,8 +308,9 @@ pub fn list_partial_eq<L: List>(a: &L, b: &dyn Reflect) -> Option<bool> {
}
for (a_value, b_value) in a.iter().zip(list.iter()) {
if let Some(false) | None = a_value.reflect_partial_eq(b_value) {
return Some(false);
let eq_result = a_value.reflect_partial_eq(b_value);
if let failed @ (Some(false) | None) = eq_result {
return failed;
}
}

View file

@ -344,6 +344,8 @@ impl<'a> ExactSizeIterator for MapIter<'a> {}
/// - `b` is the same length as `a`;
/// - For each key-value pair in `a`, `b` contains a value for the given key,
/// and [`Reflect::reflect_partial_eq`] returns `Some(true)` for the two values.
///
/// Returns [`None`] if the comparison couldn't even be performed.
#[inline]
pub fn map_partial_eq<M: Map>(a: &M, b: &dyn Reflect) -> Option<bool> {
let map = if let ReflectRef::Map(map) = b.reflect_ref() {
@ -358,8 +360,9 @@ pub fn map_partial_eq<M: Map>(a: &M, b: &dyn Reflect) -> Option<bool> {
for (key, value) in a.iter() {
if let Some(map_value) = map.get(key) {
if let Some(false) | None = value.reflect_partial_eq(map_value) {
return Some(false);
let eq_result = value.reflect_partial_eq(map_value);
if let failed @ (Some(false) | None) = eq_result {
return failed;
}
} else {
return Some(false);

View file

@ -437,6 +437,8 @@ impl Typed for DynamicStruct {
/// - For each field in `a`, `b` contains a field with the same name and
/// [`Reflect::reflect_partial_eq`] returns `Some(true)` for the two field
/// values.
///
/// Returns [`None`] if the comparison couldn't even be performed.
#[inline]
pub fn struct_partial_eq<S: Struct>(a: &S, b: &dyn Reflect) -> Option<bool> {
let struct_value = if let ReflectRef::Struct(struct_value) = b.reflect_ref() {
@ -452,8 +454,9 @@ pub fn struct_partial_eq<S: Struct>(a: &S, b: &dyn Reflect) -> Option<bool> {
for (i, value) in struct_value.iter_fields().enumerate() {
let name = struct_value.name_at(i).unwrap();
if let Some(field_value) = a.field(name) {
if let Some(false) | None = field_value.reflect_partial_eq(value) {
return Some(false);
let eq_result = field_value.reflect_partial_eq(value);
if let failed @ (Some(false) | None) = eq_result {
return failed;
}
} else {
return Some(false);

View file

@ -369,6 +369,8 @@ pub fn tuple_apply<T: Tuple>(a: &mut T, b: &dyn Reflect) {
/// - `b` is a tuple;
/// - `b` has the same number of elements as `a`;
/// - [`Reflect::reflect_partial_eq`] returns `Some(true)` for pairwise elements of `a` and `b`.
///
/// Returns [`None`] if the comparison couldn't even be performed.
#[inline]
pub fn tuple_partial_eq<T: Tuple>(a: &T, b: &dyn Reflect) -> Option<bool> {
let b = if let ReflectRef::Tuple(tuple) = b.reflect_ref() {
@ -382,9 +384,9 @@ pub fn tuple_partial_eq<T: Tuple>(a: &T, b: &dyn Reflect) -> Option<bool> {
}
for (a_field, b_field) in a.iter_fields().zip(b.iter_fields()) {
match a_field.reflect_partial_eq(b_field) {
Some(false) | None => return Some(false),
Some(true) => {}
let eq_result = a_field.reflect_partial_eq(b_field);
if let failed @ (Some(false) | None) = eq_result {
return failed;
}
}

View file

@ -349,6 +349,8 @@ impl Typed for DynamicTupleStruct {
/// - `b` is a tuple struct;
/// - `b` has the same number of fields as `a`;
/// - [`Reflect::reflect_partial_eq`] returns `Some(true)` for pairwise fields of `a` and `b`.
///
/// Returns [`None`] if the comparison couldn't even be performed.
#[inline]
pub fn tuple_struct_partial_eq<S: TupleStruct>(a: &S, b: &dyn Reflect) -> Option<bool> {
let tuple_struct = if let ReflectRef::TupleStruct(tuple_struct) = b.reflect_ref() {
@ -363,8 +365,9 @@ pub fn tuple_struct_partial_eq<S: TupleStruct>(a: &S, b: &dyn Reflect) -> Option
for (i, value) in tuple_struct.iter_fields().enumerate() {
if let Some(field_value) = a.field(i) {
if let Some(false) | None = field_value.reflect_partial_eq(value) {
return Some(false);
let eq_result = field_value.reflect_partial_eq(value);
if let failed @ (Some(false) | None) = eq_result {
return failed;
}
} else {
return Some(false);