//! Utility similar to provided by `owning_ref` crate. use std::fmt; use std::fmt::Debug; use std::ops::Deref; use std::sync::Arc; enum Owner { Arc(Arc), Static(&'static A), } impl Deref for Owner { type Target = A; fn deref(&self) -> &A { match self { Owner::Arc(a) => &*a, Owner::Static(a) => a, } } } pub(crate) struct OwningRef { owner: Owner, ptr: *const B, } unsafe impl Sync for OwningRef {} unsafe impl Send for OwningRef {} impl Deref for OwningRef { type Target = B; fn deref(&self) -> &B { // SAFETY: `self.owner` owns the data and it is not movable. unsafe { &*self.ptr } } } impl Clone for Owner { fn clone(&self) -> Owner { match self { Owner::Arc(arc) => Owner::Arc(arc.clone()), Owner::Static(ptr) => Owner::Static(ptr), } } } impl Clone for OwningRef { fn clone(&self) -> OwningRef { OwningRef { ptr: self.ptr, owner: self.owner.clone(), } } } impl Debug for OwningRef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { Debug::fmt(&**self, f) } } impl OwningRef { pub(crate) fn new_arc(arc: Arc) -> OwningRef { OwningRef { ptr: Arc::as_ptr(&arc), owner: Owner::Arc(arc), } } pub(crate) fn new_static(ptr: &'static A) -> OwningRef { OwningRef { ptr, owner: Owner::Static(ptr), } } pub(crate) fn owner(&self) -> &A { &self.owner } } impl OwningRef { pub(crate) fn _map(self, f: impl FnOnce(&B) -> &C) -> OwningRef { let ptr = f(&*self); OwningRef { ptr, owner: self.owner, } } pub(crate) fn flat_map_slice<'x, C, T: FnOnce(&B) -> &[C]>( &self, f: T, ) -> impl Iterator> + '_ where C: 'static, { f(&self).into_iter().map(|ptr| OwningRef { ptr, owner: self.owner.clone(), }) } }