use std::{mem, pin};
pub unsafe trait Project {
type App;
fn shared(self: pin::Pin<&Self>) -> pin::Pin<&Self::App>;
fn exclusive(self: pin::Pin<&mut Self>) -> pin::Pin<&mut Self::App>;
}
unsafe impl<T> Project for pin::Pin<&mut T> {
type App = T;
fn shared(self: pin::Pin<&Self>) -> pin::Pin<&T> {
self.get_ref().as_ref()
}
fn exclusive(self: pin::Pin<&mut Self>) -> pin::Pin<&mut T> {
self.get_mut().as_mut()
}
}
unsafe impl<T> Project for mem::ManuallyDrop<T> {
type App = T;
fn shared(self: pin::Pin<&Self>) -> pin::Pin<&T> {
unsafe { self.map_unchecked(|value| &**value) }
}
fn exclusive(self: pin::Pin<&mut Self>) -> pin::Pin<&mut T> {
unsafe { self.map_unchecked_mut(|value| &mut **value) }
}
}