lang_extension/any/
as_macro.rs

1#![allow(dead_code)]
2#[macro_export]
3macro_rules! as_boxed {
4    ($trait:tt) => {
5    fn clone_boxed(&self) -> Box<dyn $trait>;
6
7    fn to_boxed(self) -> Box<dyn $trait>;
8    };
9
10    ($trait:tt<$($param:tt), *>) => {
11    fn clone_boxed(&self) -> Box<dyn $trait<$($param), *>>;
12
13    fn to_boxed(self) -> Box<dyn $trait<$($param), *>>;
14    };
15
16    (impl $trait:tt) => {
17    fn clone_boxed(&self) -> Box<dyn $trait> {
18        Box::new(self.clone())
19    }
20
21    fn to_boxed(self) -> Box<dyn $trait> {
22        Box::new(self)
23    }
24    };
25
26    (impl $trait:tt<$($param:tt), *>) => {
27    fn clone_boxed(&self) -> Box<dyn $trait<$($param), *>> {
28        Box::new(self.clone())
29    }
30
31    fn to_boxed(self) -> Box<dyn $trait<$($param), *>> {
32        Box::new(self)
33    }
34    };
35
36    (impl Hash for $trait:tt) => {
37impl std::hash::Hash for Box<dyn $trait> {
38    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
39        state.write_u64(self.as_ref().hashcode());
40    }
41}
42    };
43
44    (impl Hash for $trait:tt<$($param:tt), *>) => {
45impl<$($param), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
46    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
47        state.write_u64(self.as_ref().hashcode());
48    }
49}
50    };
51
52    (impl Hash for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
53impl<$($param: $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
54    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
55        state.write_u64(self.as_ref().hashcode());
56    }
57}
58    };
59
60    (impl Hash for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
61impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
62    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
63        state.write_u64(self.as_ref().hashcode());
64    }
65}
66    };
67
68    (impl Hash for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
69impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
70    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
71        state.write_u64(self.as_ref().hashcode());
72    }
73}
74    };
75
76    (impl Hash for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
77impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> std::hash::Hash for Box<dyn $trait<$($param), *>> {
78    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
79        state.write_u64(self.as_ref().hashcode());
80    }
81}
82    };
83
84    (impl PartialEq for $trait:tt) => {
85impl PartialEq for Box<dyn $trait> {
86    fn eq(&self, other: &Self) -> bool {
87        self.as_ref().equals(other.as_ref().as_any_ref())
88    }
89}
90    };
91
92    (impl PartialEq for $trait:tt<$($param:tt), *>) => {
93impl<$($param), *> PartialEq for Box<dyn $trait<$($param), *>> {
94    fn eq(&self, other: &Self) -> bool {
95        self.as_ref().equals(other.as_ref().as_any_ref())
96    }
97}
98    };
99
100    (impl PartialEq for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
101impl<$($param: $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
102    fn eq(&self, other: &Self) -> bool {
103        self.as_ref().equals(other.as_ref().as_any_ref())
104    }
105}
106    };
107
108    (impl PartialEq for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
109impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
110    fn eq(&self, other: &Self) -> bool {
111        self.as_ref().equals(other.as_ref().as_any_ref())
112    }
113}
114    };
115
116    (impl PartialEq for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
117impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
118    fn eq(&self, other: &Self) -> bool {
119        self.as_ref().equals(other.as_ref().as_any_ref())
120    }
121}
122    };
123
124    (impl PartialEq for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
125impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> PartialEq for Box<dyn $trait<$($param), *>> {
126    fn eq(&self, other: &Self) -> bool {
127        self.as_ref().equals(other.as_ref().as_any_ref())
128    }
129}
130    };
131
132    (impl Eq for $trait:tt) => {
133impl Eq for Box<dyn $trait> { }
134    };
135
136    (impl Eq for $trait:tt<$($param:tt), *>) => {
137impl<$($param), *> Eq for Box<dyn $trait<$($param), *>> { }
138    };
139
140    (impl Eq for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
141impl<$($param: $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
142    };
143
144    (impl Eq for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
145impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
146    };
147
148    (impl Eq for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
149impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
150    };
151
152    (impl Eq for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
153impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> Eq for Box<dyn $trait<$($param), *>> { }
154    };
155
156    (impl Clone for $trait:tt) => {
157impl Clone for Box<dyn $trait> {
158    fn clone(&self) -> Self {
159        $trait::clone_boxed(self.as_ref())
160    }
161}
162    };
163
164    (impl Clone for $trait:tt<$($param:tt), *>) => {
165impl<$($param), *> Clone for Box<dyn $trait<$($param), *>> {
166    fn clone(&self) -> Self {
167        $trait::clone_boxed(self.as_ref())
168    }
169}
170    };
171
172    (impl Clone for $trait:tt<$($param:tt: $constraint0:tt $(+ $constraint:tt)*), *>) => {
173impl<$($param: $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
174    fn clone(&self) -> Self {
175        $trait::clone_boxed(self.as_ref())
176    }
177}
178    };
179
180    (impl Clone for $trait:tt<$($param:tt: ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
181impl<$($param: ?Sized + $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
182    fn clone(&self) -> Self {
183        $trait::clone_boxed(self.as_ref())
184    }
185}
186    };
187
188    (impl Clone for $trait:tt<$($param:tt: 'static + $constraint0:tt $(+ $constraint:tt)*), *>) => {
189impl<$($param: 'static + $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
190    fn clone(&self) -> Self {
191        $trait::clone_boxed(self.as_ref())
192    }
193}
194    };
195
196    (impl Clone for $trait:tt<$($param:tt: 'static + ?Sized + $constraint0:tt $(+ $constraint:tt)*), *>) => {
197impl<$($param: 'static + ?Sized + $constraint0 $(+ $constraint)*), *> Clone for Box<dyn $trait<$($param), *>> {
198    fn clone(&self) -> Self {
199        $trait::clone_boxed(self.as_ref())
200    }
201}
202    };
203}
204
205#[macro_export]
206macro_rules! as_trait {
207    ($trait: tt) => {
208    fn as_trait_ref(&self) -> &dyn $trait;
209
210    fn as_trait_mut(&mut self) -> &mut dyn $trait;
211    };
212
213    ($trait:tt<$($param:tt), *>) => {
214    fn as_trait_ref(&self) -> &dyn $trait<$($param), *>;
215
216    fn as_trait_mut(&mut self) -> &mut dyn $trait<$($param), *>;
217    };
218
219    (impl $trait: tt) => {
220    fn as_trait_ref(&self) -> &dyn $trait {
221        self
222    }
223
224    fn as_trait_mut(&mut self) -> &mut dyn $trait {
225        self
226    }
227    };
228
229    (impl $trait:tt<$($param:tt), *>) => {
230    fn as_trait_ref(&self) -> &dyn $trait<$($param), *> {
231        self
232    }
233
234    fn as_trait_mut(&mut self) -> &mut dyn $trait<$($param), *> {
235        self
236    }
237    };
238}
239
240#[allow(dead_code)]
241#[cfg(test)]
242mod tests {
243    use crate::any::*;
244    use crate::*;
245    use std::fmt::Debug;
246    use std::marker::*;
247
248    trait SomeType: Key {
249        fn say(&self);
250
251        as_boxed!(SomeType);
252        as_trait!(SomeType);
253    }
254
255    as_boxed!(impl Hash for SomeType);
256    as_boxed!(impl PartialEq for SomeType);
257    as_boxed!(impl Eq for SomeType);
258    as_boxed!(impl Clone for SomeType);
259
260    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
261    struct ST {}
262
263    impl SomeType for ST {
264        fn say(&self) {}
265
266        as_boxed!(impl SomeType);
267        as_trait!(impl SomeType);
268    }
269
270    trait SomeType1<K>: Key {
271        fn say(&self, k: K);
272
273        as_boxed!(SomeType1<K>);
274        as_trait!(SomeType1<K>);
275    }
276
277    as_boxed!(impl Hash for SomeType1<K: 'static>);
278    as_boxed!(impl PartialEq for SomeType1<K: 'static>);
279    as_boxed!(impl Eq for SomeType1<K: 'static>);
280    as_boxed!(impl Clone for SomeType1<K: 'static>);
281
282    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
283    struct ST1<K: KeyConstraint> {
284        k: PhantomData<K>,
285    }
286
287    impl<K: KeyConstraint> SomeType1<K> for ST1<K> {
288        fn say(&self, _k: K) {}
289
290        as_boxed!(impl SomeType1<K>);
291        as_trait!(impl SomeType1<K>);
292    }
293
294    trait SomeType2<K, V>: Key {
295        fn say(&self, k: K, v: V);
296
297        as_boxed!(SomeType2<K, V>);
298        as_trait!(SomeType2<K, V>);
299    }
300
301    as_boxed!(impl Hash for SomeType2<K: 'static, V: 'static>);
302    as_boxed!(impl PartialEq for SomeType2<K: 'static, V: 'static>);
303    as_boxed!(impl Eq for SomeType2<K: 'static, V: 'static>);
304    as_boxed!(impl Clone for SomeType2<K: 'static, V: 'static>);
305
306    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
307    struct ST2<K: KeyConstraint, V: ValueConstraint> {
308        k: PhantomData<K>,
309        v: PhantomData<V>,
310    }
311
312    impl<K: KeyConstraint, V: KeyConstraint> SomeType2<K, V> for ST2<K, V> {
313        fn say(&self, _k: K, _v: V) {}
314
315        as_boxed!(impl SomeType2<K, V>);
316        as_trait!(impl SomeType2<K, V>);
317    }
318
319    trait SomeType3<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>: Key {
320        fn say(&self, k: K, v: V);
321
322        as_boxed!(SomeType3<K, V>);
323        as_trait!(SomeType3<K, V>);
324    }
325
326    as_boxed!(impl Hash for SomeType3<K: KeyConstraint, V: ValueConstraint>);
327    as_boxed!(impl PartialEq for SomeType3<K: KeyConstraint, V: ValueConstraint>);
328    as_boxed!(impl Eq for SomeType3<K: KeyConstraint, V: ValueConstraint>);
329    as_boxed!(impl Clone for SomeType3<K: KeyConstraint, V: ValueConstraint>);
330
331    #[derive(Clone, PartialEq, Eq, Hash, Debug)]
332    struct ST3<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint> {
333        k: PhantomData<K>,
334        v: PhantomData<V>,
335    }
336
337    impl<K: ?Sized + KeyConstraint, V: ?Sized + KeyConstraint> SomeType3<K, V> for ST3<K, V> {
338        fn say(&self, _k: K, _v: V) {}
339
340        as_boxed!(impl SomeType3<K, V>);
341        as_trait!(impl SomeType3<K, V>);
342    }
343
344    trait SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>: Key {
345        fn say(&self, k: K, v: V);
346
347        as_boxed!(SomeType4<K, V>);
348        as_trait!(SomeType4<K, V>);
349    }
350
351    as_boxed!(impl Hash for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
352    as_boxed!(impl PartialEq for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
353    as_boxed!(impl Eq for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
354    as_boxed!(impl Clone for SomeType4<K: ?Sized + KeyConstraint, V: ?Sized + ValueConstraint>);
355
356    trait SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>: Key {
357        fn say(&self, k: K, v: V);
358
359        as_boxed!(SomeType5<K, V>);
360        as_trait!(SomeType5<K, V>);
361    }
362
363    as_boxed!(impl Hash for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
364    as_boxed!(impl PartialEq for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
365    as_boxed!(impl Eq for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
366    as_boxed!(impl Clone for SomeType5<K: 'static + KeyConstraint, V: 'static + ValueConstraint>);
367
368    trait SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>:
369        Key
370    {
371        fn say(&self, k: K, v: V);
372
373        as_boxed!(SomeType6<K, V>);
374        as_trait!(SomeType6<K, V>);
375    }
376
377    as_boxed!(impl Hash for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
378    as_boxed!(impl PartialEq for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
379    as_boxed!(impl Eq for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
380    as_boxed!(impl Clone for SomeType6<K: 'static + ?Sized + KeyConstraint, V: 'static + ?Sized + ValueConstraint>);
381
382    trait SomeType7<
383        K: 'static + ?Sized + KeyConstraint + Debug,
384        V: 'static + ?Sized + ValueConstraint,
385    >: Key
386    {
387        fn say(&self, k: K, v: V);
388
389        as_boxed!(SomeType7<K, V>);
390        as_trait!(SomeType7<K, V>);
391    }
392
393    as_boxed!(impl Hash for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
394    as_boxed!(impl PartialEq for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
395    as_boxed!(impl Eq for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
396    as_boxed!(impl Clone for SomeType7<K: 'static + ?Sized + KeyConstraint + Debug, V: 'static + ?Sized + ValueConstraint>);
397}