field_project/
pin.rs

1use core::{ops::Deref, pin::Pin};
2use std::ops::DerefMut;
3use crate::{Project, ProjectMut};
4
5/// [`Project'] is used to "project" a generic type onto a field of that type that's wrapped.
6impl<P> Project for Pin<P> where P: Deref {
7    type Base = <P as Deref>::Target;
8    type Output<'a, Field: 'a> where Self: 'a = Pin<&'a Field>;
9
10    unsafe fn project<'a, Field: ?Sized>(&'a self, project_field: fn(*const Self::Base) -> *const Field) -> Pin<&'a Field> {
11        unsafe {
12            self.as_ref().map_unchecked(|base| &*project_field(base))
13        }
14    }
15}
16
17impl<P> ProjectMut for Pin<P> where P: DerefMut {
18    type OutputMut<'a, Field: 'a> where Self: 'a = Pin<&'a mut Field>;
19
20    unsafe fn project_mut<'a, Field: ?Sized>(&'a mut self, project_field: fn(*mut Self::Base) -> *mut Field) -> Pin<&'a mut Field> {
21        unsafe {
22            self.as_mut().map_unchecked_mut(|base| &mut *project_field(base))
23        }
24    }
25}
26
27// impl<T> ProjectMut for Pin<&'_ mut T> {
28//     type OutputMut<'a, Field: 'a> where Self: 'a = Pin<&'a mut Field>;
29
30//     fn project_mut<'a, Field: ?Sized>(&'a mut self, project_field: fn(*mut Self::Base) -> *mut Field) -> Pin<&'a mut Field> {
31//         unsafe {
32//             self.as_mut().map_unchecked_mut(|base| &mut *project_field(base))
33//         }
34//     }
35// }