protobuf/
owning_ref.rs

1//! Utility similar to provided by `owning_ref` crate.
2
3use 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        // SAFETY: `self.owner` owns the data and it is not movable.
37        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}