cfx_storage/utils/
deref_plus_impl_or_borrow_self.rs1pub trait DerefPlusSelf {
10 type Target: ?Sized;
11
12 fn deref(&self) -> &Self::Target;
13}
14
15pub trait DerefMutPlusSelf {
16 type Target: ?Sized;
17
18 fn deref_mut(&mut self) -> &mut Self::Target;
19}
20
21macro_rules! enable_deref_for_self {
27 ($type:ty) => {
28 impl DerefPlusSelf for $type {
29 type Target = Self;
30
31 fn deref(&self) -> &Self { self }
32 }
33 impl DerefMutPlusSelf for $type {
34 type Target = Self;
35
36 fn deref_mut(&mut self) -> &mut Self { self }
37 }
38 };
39}
40
41impl<D: Deref<Target = T>, T: ?Sized> DerefPlusSelf for D {
42 type Target = T;
43
44 fn deref(&self) -> &T { Deref::deref(self) }
45}
46
47impl<D: DerefMut<Target = T>, T: ?Sized> DerefMutPlusSelf for D {
48 type Target = T;
49
50 fn deref_mut(&mut self) -> &mut T { DerefMut::deref_mut(self) }
51}
52
53pub trait ImplOrBorrowSelf<Trait: ?Sized> {
56 fn borrow(&self) -> &Trait;
57}
58
59pub trait ImplOrBorrowMutSelf<Trait: ?Sized> {
62 fn borrow_mut(&mut self) -> &mut Trait;
63}
64
65pub trait DerefPlusImplOrBorrowSelf<T: ?Sized> {
70 fn borrow(&self) -> &T;
71}
72
73pub trait DerefMutPlusImplOrBorrowMutSelf<T: ?Sized> {
74 fn borrow_mut(&mut self) -> &mut T;
75}
76
77macro_rules! enable_deref_plus_impl_or_borrow_self {
84 ($trait:path) => {
85 impl<'a> ImplOrBorrowSelf<dyn 'a + $trait> for dyn 'a + $trait {
86 fn borrow(&self) -> &(dyn 'a + $trait) { self }
87 }
88
89 impl<'a> ImplOrBorrowSelf<dyn 'a + $trait> for &(dyn 'a + $trait) {
90 fn borrow(&self) -> &(dyn 'a + $trait) { *self }
91 }
92
93 impl<'a, T: 'a + $trait> ImplOrBorrowSelf<dyn 'a + $trait> for T {
94 fn borrow(&self) -> &(dyn 'a + $trait) { self }
95 }
96
97 impl<'a> DerefPlusImplOrBorrowSelf<dyn 'a + $trait>
98 for dyn 'a + $trait
99 {
100 fn borrow(&self) -> &(dyn 'a + $trait) { self }
101 }
102
103 impl<
104 'a,
105 D: DerefPlusSelf<Target = T>,
106 T: 'a + ImplOrBorrowSelf<dyn 'a + $trait> + ?Sized,
107 > DerefPlusImplOrBorrowSelf<dyn 'a + $trait> for D
108 {
109 fn borrow(&self) -> &(dyn 'a + $trait) {
110 <T as ImplOrBorrowSelf<dyn 'a + $trait>>::borrow(self.deref())
111 }
112 }
113 };
114}
115
116macro_rules! enable_deref_mut_plus_impl_or_borrow_mut_self {
117 ($trait:path) => {
118 impl<'a> ImplOrBorrowMutSelf<dyn 'a + $trait> for dyn 'a + $trait {
119 fn borrow_mut(&mut self) -> &mut (dyn 'a + $trait) { self }
120 }
121
122 impl<'a> ImplOrBorrowMutSelf<dyn 'a + $trait>
123 for &mut (dyn 'a + $trait)
124 {
125 fn borrow_mut(&mut self) -> &mut (dyn 'a + $trait) { *self }
126 }
127
128 impl<'a, T: 'a + $trait> ImplOrBorrowMutSelf<dyn 'a + $trait> for T {
129 fn borrow_mut(&mut self) -> &mut (dyn 'a + $trait) { self }
130 }
131
132 impl<'a> DerefMutPlusImplOrBorrowMutSelf<dyn 'a + $trait>
133 for dyn 'a + $trait
134 {
135 fn borrow_mut(&mut self) -> &mut (dyn 'a + $trait) { self }
136 }
137
138 impl<
139 'a,
140 D: DerefMutPlusSelf<Target = T>,
141 T: 'a + ImplOrBorrowMutSelf<dyn 'a + $trait> + ?Sized,
142 > DerefMutPlusImplOrBorrowMutSelf<dyn 'a + $trait> for D
143 {
144 fn borrow_mut(&mut self) -> &mut (dyn 'a + $trait) {
145 <T as ImplOrBorrowMutSelf<dyn 'a + $trait>>::borrow_mut(
146 self.deref_mut(),
147 )
148 }
149 }
150 };
151}
152
153#[cfg(test)]
154mod test {
155 use super::*;
156
157 enable_deref_for_self!(str);
158 enable_deref_for_self!([u8]);
159 enable_deref_for_self!(my_vec::MyVec<u8>);
160
161 enable_deref_plus_impl_or_borrow_self!(TestTrait);
162 enable_deref_for_self!(Test);
163
164 trait TestTrait {
165 fn print(&self, x: i32) {
166 println!("{}", x);
167 }
168 }
169 struct Test {}
170 mod my_vec {
171 #[allow(dead_code)]
172 pub struct MyVec<T>(#[allow(unused)] pub Vec<T>);
173 }
174
175 impl TestTrait for Test {}
176
177 #[allow(unused)]
179 fn test<'a>(x: &'a i32) {
180 let test = Test {};
181 <Test as DerefPlusImplOrBorrowSelf<dyn TestTrait>>::borrow(&test)
182 .print(*x);
183 <&Test as DerefPlusImplOrBorrowSelf<dyn TestTrait>>::borrow(&&test)
184 .print(*x);
185 let boxed: Box<dyn 'a + TestTrait> = Box::new(test);
186 <dyn 'a + TestTrait as DerefPlusImplOrBorrowSelf<dyn 'a + TestTrait>>::borrow(
187 Deref::deref(&boxed),
188 )
189 .print(*x);
190 <&(dyn 'a + TestTrait) as DerefPlusImplOrBorrowSelf<
191 dyn 'a + TestTrait,
192 >>::borrow(&Deref::deref(&boxed))
193 .print(*x);
194 <Box<dyn 'a + TestTrait> as DerefPlusImplOrBorrowSelf<
195 dyn 'a + TestTrait,
196 >>::borrow(&boxed)
197 .print(*x);
198 }
199}
200
201use std::ops::{Deref, DerefMut};