use std::ops::Deref;
use bevy::prelude::{DetectChanges, Ref as BRef};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Ref<'w, T: ?Sized> {
pub(crate) value: &'w T,
pub(crate) is_added: bool,
pub(crate) is_changed: bool,
}
impl<'w, T: ?Sized> Ref<'w, T> {
#[must_use]
pub const fn is_added(&self) -> bool {
self.is_added
}
#[must_use]
pub const fn is_changed(&self) -> bool {
self.is_changed
}
#[must_use]
pub const fn into_inner(self) -> &'w T {
self.value
}
pub fn map_failable<E, U: ?Sized>(
self,
f: impl FnOnce(&T) -> Result<&U, E>,
) -> Result<Ref<'w, U>, E> {
Ok(Ref {
value: f(self.value)?,
is_added: self.is_added,
is_changed: self.is_changed,
})
}
#[must_use]
pub fn map<U: ?Sized>(self, f: impl FnOnce(&T) -> &U) -> Ref<'w, U> {
Ref {
value: f(self.value),
is_added: self.is_added,
is_changed: self.is_changed,
}
}
#[must_use]
pub fn map_from<U: ?Sized>(bevy: BRef<'w, U>, f: impl FnOnce(&U) -> &T) -> Self {
Ref {
is_added: bevy.is_added(),
is_changed: bevy.is_changed(),
value: f(bevy.into_inner()),
}
}
}
impl<'w, T: ?Sized> From<BRef<'w, T>> for Ref<'w, T> {
fn from(value: BRef<'w, T>) -> Self {
Ref::map_from(value, |i| i)
}
}
impl<'w, T: ?Sized> AsRef<T> for Ref<'w, T> {
fn as_ref(&self) -> &T {
self.value
}
}
impl<'w, T: ?Sized> Deref for Ref<'w, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.value
}
}
impl<'w, 'a, T> IntoIterator for &'a Ref<'w, T>
where
&'a T: IntoIterator,
{
type Item = <&'a T as IntoIterator>::Item;
type IntoIter = <&'a T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.value.into_iter()
}
}