clone_behavior/
mirrored.rs1#![expect(clippy::absolute_paths, reason = "there's a lot of random types used")]
2#![warn(clippy::missing_inline_in_public_items, reason = "almost everything is very short")]
3
4use crate::call_varargs_macro;
5use crate::speed::{Speed, NearInstant, ConstantTime, LogTime, AnySpeed};
6
7
8pub trait MirroredClone<S: Speed>: Sized {
38 #[must_use]
46 fn mirrored_clone(&self) -> Self;
47}
48
49
50macro_rules! non_recursive_near_instant {
51 ($($({for $($bounds:tt)+})? $type:ty),* $(,)?) => {
52 $(
53 impl<$($($bounds)+)?> MirroredClone<NearInstant> for $type {
54 #[inline]
55 fn mirrored_clone(&self) -> Self {
56 self.clone()
57 }
58 }
59 )*
60 };
61}
62
63non_recursive_near_instant! {
64 (),
65 core::convert::Infallible,
66 {for T} core::iter::Empty<T>,
67 {for T: ?Sized} core::marker::PhantomData<T>,
68 core::marker::PhantomPinned,
69 core::ops::RangeFull,
70}
71
72#[cfg(feature = "alloc")]
73macro_rules! refcounted {
74 ($($t:ident $refcounted:ty),* $(,)?) => {
75 $(
76 impl<S: Speed, $t: ?Sized> MirroredClone<S> for $refcounted {
77 #[inline]
78 fn mirrored_clone(&self) -> Self {
79 self.clone()
80 }
81 }
82 )*
83 };
84}
85
86#[cfg(feature = "alloc")]
87refcounted!(
88 T alloc::rc::Rc<T>,
89 T alloc::rc::Weak<T>,
90 T alloc::sync::Arc<T>,
91 T alloc::sync::Weak<T>,
92);
93
94macro_rules! function {
95 ($($args:ident),*) => {
96 impl<R, $($args),*> MirroredClone<NearInstant> for fn($($args),*) -> R {
97 #[inline]
98 fn mirrored_clone(&self) -> Self {
99 *self
100 }
101 }
102 };
103}
104
105macro_rules! pinned_refcounted {
106 ($($t:ident $refcounted:ty),* $(,)?) => {
107 $(
108 #[cfg(feature = "alloc")]
109 impl<S: Speed, $t: ?Sized> MirroredClone<S> for core::pin::Pin<$refcounted> {
110 #[inline]
111 fn mirrored_clone(&self) -> Self {
112 self.clone()
113 }
114 }
115 )*
116 };
117}
118
119pinned_refcounted! {
120 T alloc::rc::Rc<T>,
121 T alloc::rc::Weak<T>,
122 T alloc::sync::Arc<T>,
123 T alloc::sync::Weak<T>,
124}
125
126function!();
127call_varargs_macro!(function);
128
129macro_rules! make_tuple_macro {
130 ($name:ident, $speed:ident, $dollar:tt) => {
131 macro_rules! $name {
132 ($dollar($dollar args:ident),+) => {
133 impl<$dollar($dollar args: MirroredClone<$speed>),+> MirroredClone<$speed>
134 for ($dollar($dollar args,)+)
135 {
136 #[inline]
137 fn mirrored_clone(&self) -> Self {
138 #[expect(
139 non_snake_case,
140 reason = "using `Tn` as the variable of type `Tn`",
141 )]
142 let ($dollar($dollar args,)+) = self;
143 (
144 $dollar($dollar args.mirrored_clone(),)+
145 )
146 }
147 }
148 };
149 }
150 };
151}
152
153make_tuple_macro!(tuple_constant, ConstantTime, $);
154make_tuple_macro!(tuple_log, LogTime, $);
155make_tuple_macro!(tuple_any, AnySpeed, $);
156
157call_varargs_macro!(tuple_constant);
158call_varargs_macro!(tuple_log);
159call_varargs_macro!(tuple_any);
160
161impl<S: Speed, T: MirroredClone<S>> MirroredClone<S> for Option<T> {
162 #[inline]
163 fn mirrored_clone(&self) -> Self {
164 self.as_ref().map(T::mirrored_clone)
165 }
166}
167
168impl<S: Speed, T: MirroredClone<S>, E: MirroredClone<S>> MirroredClone<S> for Result<T, E> {
169 #[inline]
170 fn mirrored_clone(&self) -> Self {
171 self.as_ref()
172 .map(T::mirrored_clone)
173 .map_err(E::mirrored_clone)
174 }
175}