/rust/registry/src/index.crates.io-1949cf8c6b5b557f/dyn-clone-1.0.20/src/macros.rs
Line | Count | Source |
1 | | use crate::DynClone; |
2 | | |
3 | | /// Implement the standard library `Clone` for a trait object that has |
4 | | /// `DynClone` as a supertrait. |
5 | | /// |
6 | | /// ``` |
7 | | /// use dyn_clone::DynClone; |
8 | | /// |
9 | | /// trait MyTrait: DynClone { |
10 | | /// /* ... */ |
11 | | /// } |
12 | | /// |
13 | | /// dyn_clone::clone_trait_object!(MyTrait); |
14 | | /// |
15 | | /// // Now data structures containing Box<dyn MyTrait> can derive Clone. |
16 | | /// #[derive(Clone)] |
17 | | /// struct Container { |
18 | | /// trait_object: Box<dyn MyTrait>, |
19 | | /// } |
20 | | /// ``` |
21 | | /// |
22 | | /// The macro supports traits that have type parameters and/or `where` clauses. |
23 | | /// |
24 | | /// ``` |
25 | | /// use dyn_clone::DynClone; |
26 | | /// use std::io::Read; |
27 | | /// |
28 | | /// trait Difficult<R>: DynClone where R: Read { |
29 | | /// /* ... */ |
30 | | /// } |
31 | | /// |
32 | | /// dyn_clone::clone_trait_object!(<R> Difficult<R> where R: Read); |
33 | | /// ``` |
34 | | #[macro_export] |
35 | | macro_rules! clone_trait_object { |
36 | | ($($path:tt)+) => { |
37 | | $crate::__internal_clone_trait_object!(begin $($path)+); |
38 | | }; |
39 | | } |
40 | | |
41 | | #[doc(hidden)] |
42 | | #[macro_export] |
43 | | macro_rules! __internal_clone_trait_object { |
44 | | // Invocation started with `<`, parse generics. |
45 | | (begin < $($rest:tt)*) => { |
46 | | $crate::__internal_clone_trait_object!(generics () () $($rest)*); |
47 | | }; |
48 | | |
49 | | // Invocation did not start with `<`. |
50 | | (begin $first:tt $($rest:tt)*) => { |
51 | | $crate::__internal_clone_trait_object!(path () ($first) $($rest)*); |
52 | | }; |
53 | | |
54 | | // End of generics. |
55 | | (generics ($($generics:tt)*) () > $($rest:tt)*) => { |
56 | | $crate::__internal_clone_trait_object!(path ($($generics)*) () $($rest)*); |
57 | | }; |
58 | | |
59 | | // Generics open bracket. |
60 | | (generics ($($generics:tt)*) ($($brackets:tt)*) < $($rest:tt)*) => { |
61 | | $crate::__internal_clone_trait_object!(generics ($($generics)* <) ($($brackets)* <) $($rest)*); |
62 | | }; |
63 | | |
64 | | // Generics close bracket. |
65 | | (generics ($($generics:tt)*) (< $($brackets:tt)*) > $($rest:tt)*) => { |
66 | | $crate::__internal_clone_trait_object!(generics ($($generics)* >) ($($brackets)*) $($rest)*); |
67 | | }; |
68 | | |
69 | | // Token inside of generics. |
70 | | (generics ($($generics:tt)*) ($($brackets:tt)*) $first:tt $($rest:tt)*) => { |
71 | | $crate::__internal_clone_trait_object!(generics ($($generics)* $first) ($($brackets)*) $($rest)*); |
72 | | }; |
73 | | |
74 | | // End with `where` clause. |
75 | | (path ($($generics:tt)*) ($($path:tt)*) where $($rest:tt)*) => { |
76 | | $crate::__internal_clone_trait_object!(impl ($($generics)*) ($($path)*) ($($rest)*)); |
77 | | }; |
78 | | |
79 | | // End without `where` clause. |
80 | | (path ($($generics:tt)*) ($($path:tt)*)) => { |
81 | | $crate::__internal_clone_trait_object!(impl ($($generics)*) ($($path)*) ()); |
82 | | }; |
83 | | |
84 | | // Token inside of path. |
85 | | (path ($($generics:tt)*) ($($path:tt)*) $first:tt $($rest:tt)*) => { |
86 | | $crate::__internal_clone_trait_object!(path ($($generics)*) ($($path)* $first) $($rest)*); |
87 | | }; |
88 | | |
89 | | // The impl. |
90 | | (impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => { |
91 | | #[allow(unknown_lints, non_local_definitions)] // false positive: https://github.com/rust-lang/rust/issues/121621 |
92 | | impl<'clone, $($generics)*> $crate::__private::Clone for $crate::__private::Box<dyn $($path)* + 'clone> where $($bound)* { |
93 | 0 | fn clone(&self) -> Self { |
94 | 0 | $crate::clone_box(&**self) |
95 | 0 | } Unexecuted instantiation: <alloc::boxed::Box<dyn mp4san::parse::mp4box::ParsedBox> as core::clone::Clone>::clone Unexecuted instantiation: <alloc::boxed::Box<dyn dyn_clone::DynClone> as core::clone::Clone>::clone |
96 | | } |
97 | | |
98 | | #[allow(unknown_lints, non_local_definitions)] |
99 | | impl<'clone, $($generics)*> $crate::__private::Clone for $crate::__private::Box<dyn $($path)* + $crate::__private::Send + 'clone> where $($bound)* { |
100 | 0 | fn clone(&self) -> Self { |
101 | 0 | $crate::clone_box(&**self) |
102 | 0 | } Unexecuted instantiation: <alloc::boxed::Box<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Send> as core::clone::Clone>::clone Unexecuted instantiation: <alloc::boxed::Box<dyn dyn_clone::DynClone + core::marker::Send> as core::clone::Clone>::clone |
103 | | } |
104 | | |
105 | | #[allow(unknown_lints, non_local_definitions)] |
106 | | impl<'clone, $($generics)*> $crate::__private::Clone for $crate::__private::Box<dyn $($path)* + $crate::__private::Sync + 'clone> where $($bound)* { |
107 | 0 | fn clone(&self) -> Self { |
108 | 0 | $crate::clone_box(&**self) |
109 | 0 | } Unexecuted instantiation: <alloc::boxed::Box<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Sync> as core::clone::Clone>::clone Unexecuted instantiation: <alloc::boxed::Box<dyn dyn_clone::DynClone + core::marker::Sync> as core::clone::Clone>::clone |
110 | | } |
111 | | |
112 | | #[allow(unknown_lints, non_local_definitions)] |
113 | | impl<'clone, $($generics)*> $crate::__private::Clone for $crate::__private::Box<dyn $($path)* + $crate::__private::Send + $crate::__private::Sync + 'clone> where $($bound)* { |
114 | 0 | fn clone(&self) -> Self { |
115 | 0 | $crate::clone_box(&**self) |
116 | 0 | } Unexecuted instantiation: <alloc::boxed::Box<dyn mp4san::parse::mp4box::ParsedBox + core::marker::Sync + core::marker::Send> as core::clone::Clone>::clone Unexecuted instantiation: <alloc::boxed::Box<dyn dyn_clone::DynClone + core::marker::Sync + core::marker::Send> as core::clone::Clone>::clone |
117 | | } |
118 | | }; |
119 | | } |
120 | | |
121 | | clone_trait_object!(DynClone); |