protobuf/
owning_ref.rs
1use std::fmt;
4use std::fmt::Debug;
5use std::ops::Deref;
6use std::sync::Arc;
7
8enum Owner<A: 'static> {
9 Arc(Arc<A>),
10 Static(&'static A),
11}
12
13impl<A: 'static> Deref for Owner<A> {
14 type Target = A;
15
16 fn deref(&self) -> &A {
17 match self {
18 Owner::Arc(a) => &*a,
19 Owner::Static(a) => a,
20 }
21 }
22}
23
24pub(crate) struct OwningRef<A: 'static, B: 'static> {
25 owner: Owner<A>,
26 ptr: *const B,
27}
28
29unsafe impl<A: Send + Sync + 'static, B: Send + Sync + 'static> Sync for OwningRef<A, B> {}
30unsafe impl<A: Send + Sync + 'static, B: Send + Sync + 'static> Send for OwningRef<A, B> {}
31
32impl<A: 'static, B: 'static> Deref for OwningRef<A, B> {
33 type Target = B;
34
35 fn deref(&self) -> &B {
36 unsafe { &*self.ptr }
38 }
39}
40
41impl<A: 'static> Clone for 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
50impl<A: 'static, B: 'static> Clone for 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
59impl<A: 'static, B: fmt::Debug + 'static> Debug for OwningRef<A, B> {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 Debug::fmt(&**self, f)
62 }
63}
64
65impl<A: 'static> 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
73 pub(crate) fn new_static(ptr: &'static A) -> OwningRef<A, A> {
74 OwningRef {
75 ptr,
76 owner: Owner::Static(ptr),
77 }
78 }
79
80 pub(crate) fn owner(&self) -> &A {
81 &self.owner
82 }
83}
84
85impl<A: 'static, B: 'static> OwningRef<A, B> {
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
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}