diff options
Diffstat (limited to 'ecs/src/util.rs')
-rw-r--r-- | ecs/src/util.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/ecs/src/util.rs b/ecs/src/util.rs index f4f8632..5ec21c7 100644 --- a/ecs/src/util.rs +++ b/ecs/src/util.rs @@ -1,3 +1,6 @@ +use std::cell::Ref; +use std::ops::{Deref, DerefMut}; + pub trait Sortable { type Item; @@ -46,3 +49,50 @@ impl<Item> Sortable for Vec<Item> self.sort_by_key(func) } } + +#[derive(Debug)] +pub struct RefCellRefMap<'a, Value: 'a, MappedValue: 'a> +{ + mapped_value: MappedValue, + _refcell_ref: Ref<'a, Value>, +} + +impl<'a, Value: 'a, MappedValue: 'a> RefCellRefMap<'a, Value, MappedValue> +{ + pub fn new( + refcell_ref: Ref<'a, Value>, + map_fn: impl Fn(&'a Value) -> MappedValue, + ) -> Self + { + // Convert the lifetime to 'static. This is necessary to make the compiler not + // complain about refcell_ref being moved + // + // SAFETY: This is fine since we pass it to map_fn with the original lifetime 'a + let val_ref = unsafe { &*(&*refcell_ref as *const Value) }; + + let mapped_value = map_fn(val_ref); + + Self { + mapped_value, + _refcell_ref: refcell_ref, + } + } +} + +impl<'a, Value: 'a, MappedValue: 'a> Deref for RefCellRefMap<'a, Value, MappedValue> +{ + type Target = MappedValue; + + fn deref(&self) -> &Self::Target + { + &self.mapped_value + } +} + +impl<'a, Value: 'a, MappedValue: 'a> DerefMut for RefCellRefMap<'a, Value, MappedValue> +{ + fn deref_mut(&mut self) -> &mut Self::Target + { + &mut self.mapped_value + } +} |