1use core::ops::{Deref, DerefMut};
16
17impl<Source> super::AccessAs for Source {
18 fn ref_as<T: ?Sized>(&self) -> <Self as IGuardRef<T>>::Guard<'_>
19 where
20 Self: IGuardRef<T>,
21 {
22 self.guard_ref_inner()
23 }
24 fn mut_as<T: ?Sized>(&mut self) -> <Self as IGuardMut<T>>::GuardMut<'_>
25 where
26 Self: IGuardMut<T>,
27 {
28 self.guard_mut_inner()
29 }
30}
31
32pub trait IGuardRef<T: ?Sized> {
34 type Guard<'a>: Deref<Target = T>
36 where
37 Self: 'a;
38 fn guard_ref_inner(&self) -> Self::Guard<'_>;
40}
41
42pub trait IGuardMut<T: ?Sized>: IGuardRef<T> {
44 type GuardMut<'a>: DerefMut<Target = T>
46 where
47 Self: 'a;
48 fn guard_mut_inner(&mut self) -> Self::GuardMut<'_>;
50}
51
52pub struct RefAs<'a, T, As> {
54 source: core::marker::PhantomData<&'a T>,
55 target: core::mem::ManuallyDrop<As>,
56}
57impl<T, As> Deref for RefAs<'_, T, As> {
58 type Target = As;
59 fn deref(&self) -> &Self::Target {
60 &self.target
61 }
62}
63impl<T: Into<As>, As: Into<T>> IGuardRef<As> for T {
64 type Guard<'a>
65 = RefAs<'a, T, As>
66 where
67 Self: 'a;
68
69 fn guard_ref_inner(&self) -> Self::Guard<'_> {
70 RefAs {
71 source: core::marker::PhantomData,
72 target: core::mem::ManuallyDrop::new(unsafe { core::ptr::read(self).into() }),
73 }
74 }
75}
76
77pub struct MutAs<'a, T, As: Into<T>> {
81 source: &'a mut T,
82 target: core::mem::ManuallyDrop<As>,
83}
84impl<T, As: Into<T>> Deref for MutAs<'_, T, As> {
85 type Target = As;
86 fn deref(&self) -> &Self::Target {
87 &self.target
88 }
89}
90impl<T, As: Into<T>> DerefMut for MutAs<'_, T, As> {
91 fn deref_mut(&mut self) -> &mut Self::Target {
92 &mut self.target
93 }
94}
95impl<T, As: Into<T>> Drop for MutAs<'_, T, As> {
96 fn drop(&mut self) {
97 unsafe { core::ptr::write(self.source, core::ptr::read(&*self.target).into()) }
98 }
99}
100impl<T: Into<As>, As: Into<T>> IGuardMut<As> for T {
101 type GuardMut<'a>
102 = MutAs<'a, T, As>
103 where
104 Self: 'a;
105
106 fn guard_mut_inner(&mut self) -> Self::GuardMut<'_> {
107 MutAs {
108 target: core::mem::ManuallyDrop::new(unsafe { core::ptr::read(self).into() }),
109 source: self,
110 }
111 }
112}