use std::convert::Infallible;
use std::mem;
use dupe::Clone_;
use dupe::Copy_;
use dupe::Dupe_;
use crate::values::FrozenHeap;
use crate::values::FrozenHeapRef;
use crate::values::Heap;
#[derive(Copy_, Clone_, Dupe_)]
pub struct OwnedRefFrozenRef<'f, T: ?Sized + 'static> {
owner: &'f FrozenHeapRef,
value: &'f T,
}
impl<'f, T: ?Sized> OwnedRefFrozenRef<'f, T> {
pub unsafe fn new_unchecked(
value: &'f T,
owner: &'f FrozenHeapRef,
) -> OwnedRefFrozenRef<'f, T> {
OwnedRefFrozenRef { owner, value }
}
pub fn owner(&self) -> &'f FrozenHeapRef {
self.owner
}
pub fn as_ref(self) -> &'f T {
self.value
}
pub fn add_heap_ref<'v>(self, heap: &'v FrozenHeap) -> &'v T {
heap.add_reference(self.owner);
unsafe { mem::transmute::<&'f T, &'v T>(self.value) }
}
pub fn add_unfrozen_heap_ref<'v>(self, heap: Heap<'v>) -> &'v T {
heap.add_reference(self.owner);
unsafe { mem::transmute::<&'f T, &'v T>(self.value) }
}
pub fn try_map_result<F, U: ?Sized, E>(self, f: F) -> Result<OwnedRefFrozenRef<'f, U>, E>
where
F: FnOnce(&'f T) -> Result<&'f U, E>,
{
Ok(OwnedRefFrozenRef {
owner: self.owner,
value: f(self.value)?,
})
}
pub fn map<F, U: ?Sized>(self, f: F) -> OwnedRefFrozenRef<'f, U>
where
F: FnOnce(&'f T) -> &'f U,
{
match self.try_map_result(|x| Ok::<_, Infallible>(f(x))) {
Ok(x) => x,
}
}
pub fn try_map_option<F, U: ?Sized>(self, f: F) -> Option<OwnedRefFrozenRef<'f, U>>
where
F: FnOnce(&'f T) -> Option<&'f U>,
{
self.try_map_result(|x| f(x).ok_or(())).ok()
}
}