1  //! Utility similar to provided by `owning_ref` crate.
2  
3  use std::fmt;
4  use std::fmt::Debug;
5  use std::ops::Deref;
6  use std::sync::Arc;
7  
8  enum Owner<A: 'static> {
9      Arc(Arc<A>),
10      Static(&'static A),
11  }
12  
13  impl<A: 'static> Deref for Owner<A> {
14      type Target = A;
15  
deref(&self) -> &A16      fn deref(&self) -> &A {
17          match self {
18              Owner::Arc(a) => &*a,
19              Owner::Static(a) => a,
20          }
21      }
22  }
23  
24  pub(crate) struct OwningRef<A: 'static, B: 'static> {
25      owner: Owner<A>,
26      ptr: *const B,
27  }
28  
29  unsafe impl<A: Send + Sync + 'static, B: Send + Sync + 'static> Sync for OwningRef<A, B> {}
30  unsafe impl<A: Send + Sync + 'static, B: Send + Sync + 'static> Send for OwningRef<A, B> {}
31  
32  impl<A: 'static, B: 'static> Deref for OwningRef<A, B> {
33      type Target = B;
34  
deref(&self) -> &B35      fn deref(&self) -> &B {
36          // SAFETY: `self.owner` owns the data and it is not movable.
37          unsafe { &*self.ptr }
38      }
39  }
40  
41  impl<A: 'static> Clone for Owner<A> {
clone(&self) -> Owner<A>42      fn clone(&self) -> Owner<A> {
43          match self {
44              Owner::Arc(arc) => Owner::Arc(arc.clone()),
45              Owner::Static(ptr) => Owner::Static(ptr),
46          }
47      }
48  }
49  
50  impl<A: 'static, B: 'static> Clone for OwningRef<A, B> {
clone(&self) -> OwningRef<A, B>51      fn clone(&self) -> OwningRef<A, B> {
52          OwningRef {
53              ptr: self.ptr,
54              owner: self.owner.clone(),
55          }
56      }
57  }
58  
59  impl<A: 'static, B: fmt::Debug + 'static> Debug for OwningRef<A, B> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result60      fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61          Debug::fmt(&**self, f)
62      }
63  }
64  
65  impl<A: 'static> OwningRef<A, A> {
new_arc(arc: Arc<A>) -> OwningRef<A, A>66      pub(crate) fn new_arc(arc: Arc<A>) -> OwningRef<A, A> {
67          OwningRef {
68              ptr: Arc::as_ptr(&arc),
69              owner: Owner::Arc(arc),
70          }
71      }
72  
new_static(ptr: &'static A) -> OwningRef<A, A>73      pub(crate) fn new_static(ptr: &'static A) -> OwningRef<A, A> {
74          OwningRef {
75              ptr,
76              owner: Owner::Static(ptr),
77          }
78      }
79  
owner(&self) -> &A80      pub(crate) fn owner(&self) -> &A {
81          &self.owner
82      }
83  }
84  
85  impl<A: 'static, B: 'static> OwningRef<A, B> {
_map<C>(self, f: impl FnOnce(&B) -> &C) -> OwningRef<A, C>86      pub(crate) fn _map<C>(self, f: impl FnOnce(&B) -> &C) -> OwningRef<A, C> {
87          let ptr = f(&*self);
88          OwningRef {
89              ptr,
90              owner: self.owner,
91          }
92      }
93  
flat_map_slice<'x, C, T: FnOnce(&B) -> &[C]>( &self, f: T, ) -> impl Iterator<Item = OwningRef<A, C>> + '_ where C: 'static,94      pub(crate) fn flat_map_slice<'x, C, T: FnOnce(&B) -> &[C]>(
95          &self,
96          f: T,
97      ) -> impl Iterator<Item = OwningRef<A, C>> + '_
98      where
99          C: 'static,
100      {
101          f(&self).into_iter().map(|ptr| OwningRef {
102              ptr,
103              owner: self.owner.clone(),
104          })
105      }
106  }
107