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