arc_ext/
arc.rs

1use std::{marker::PhantomData, ops::Deref, pin::Pin, sync::Arc};
2
3pub struct ArcProject<'a, 'b, T, U>
4where
5    T: ?Sized + Unpin,
6{
7    value: *const U,
8    inner: Pin<Arc<T>>,
9    _lifetime: PhantomData<&'a &'b ()>,
10}
11
12unsafe impl<T, U> Send for ArcProject<'_, '_, T, U> where T: ?Sized + Unpin {}
13
14unsafe impl<T, U> Sync for ArcProject<'_, '_, T, U> where T: ?Sized + Unpin {}
15
16impl<'a, 'b, T, U> ArcProject<'a, 'b, T, U>
17where
18    'a: 'b,
19    T: ?Sized + Unpin + 'a,
20    U: 'b,
21{
22    pub fn new<F: Fn(&'a Pin<Arc<T>>) -> &'b U>(inner: Arc<T>, deref_fn: F) -> Self {
23        let mut out = Self {
24            value: std::ptr::null(),
25            inner: Pin::new(inner),
26            _lifetime: PhantomData,
27        };
28
29        out.value = deref_fn(unsafe { std::mem::transmute(&out.inner) });
30        out
31    }
32}
33
34impl<'a, 'b, T, U> Deref for ArcProject<'a, 'b, T, U>
35where
36    'a: 'b,
37    T: ?Sized + Unpin + 'a,
38    U: 'b,
39{
40    type Target = U;
41
42    fn deref(&self) -> &'b Self::Target {
43        unsafe { &*self.value }
44    }
45}