1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3#[cfg(feature = "ops")]
4pub(crate) mod deref {
5 use crate::derive::prelude::*;
6
7 pub(crate) const NAME: &[&str] = &["Deref"];
8
9 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
10 Ok(derive_trait(data, &parse_quote!(::core::ops::Deref), None, parse_quote! {
11 trait Deref {
12 type Target;
13 #[inline]
14 fn deref(&self) -> &Self::Target;
15 }
16 }))
17 }
18}
19
20#[cfg(feature = "ops")]
21pub(crate) mod deref_mut {
22 use crate::derive::prelude::*;
23
24 pub(crate) const NAME: &[&str] = &["DerefMut"];
25
26 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
27 Ok(derive_trait(
28 data,
29 &parse_quote!(::core::ops::DerefMut),
30 Some(format_ident!("Target")),
31 parse_quote! {
32 trait DerefMut: ::core::ops::Deref {
33 #[inline]
34 fn deref_mut(&mut self) -> &mut Self::Target;
35 }
36 },
37 ))
38 }
39}
40
41#[cfg(feature = "ops")]
42pub(crate) mod index {
43 use crate::derive::prelude::*;
44
45 pub(crate) const NAME: &[&str] = &["Index"];
46
47 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
48 Ok(derive_trait(data, &parse_quote!(::core::ops::Index), None, parse_quote! {
49 trait Index<__Idx> {
50 type Output;
51 #[inline]
52 fn index(&self, index: __Idx) -> &Self::Output;
53 }
54 }))
55 }
56}
57
58#[cfg(feature = "ops")]
59pub(crate) mod index_mut {
60 use crate::derive::prelude::*;
61
62 pub(crate) const NAME: &[&str] = &["IndexMut"];
63
64 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
65 Ok(derive_trait(
66 data,
67 &parse_quote!(::core::ops::IndexMut),
68 Some(format_ident!("Output")),
69 parse_quote! {
70 trait IndexMut<__Idx>: ::core::ops::Index<__Idx> {
71 #[inline]
72 fn index_mut(&mut self, index: __Idx) -> &mut Self::Output;
73 }
74 },
75 ))
76 }
77}
78
79#[cfg(feature = "ops")]
80pub(crate) mod range_bounds {
81 use crate::derive::prelude::*;
82
83 pub(crate) const NAME: &[&str] = &["RangeBounds"];
84
85 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
86 Ok(derive_trait(data, &parse_quote!(::core::ops::RangeBounds), None, parse_quote! {
87 trait RangeBounds<__T: ?Sized> {
88 #[inline]
89 fn start_bound(&self) -> ::core::ops::Bound<&__T>;
90 #[inline]
91 fn end_bound(&self) -> ::core::ops::Bound<&__T>;
92 }
93 }))
94 }
95}
96
97#[cfg(feature = "coroutine_trait")]
98pub(crate) mod coroutine {
99 use crate::derive::prelude::*;
100
101 pub(crate) const NAME: &[&str] = &["Coroutine"];
102
103 pub(crate) fn derive(cx: &Context, data: &Data) -> Result<TokenStream> {
104 cx.needs_pin_projection();
105
106 let ident = &data.ident;
107 let pin = quote!(::core::pin::Pin);
108 let trait_ = parse_quote!(::core::ops::Coroutine);
109 let mut impl_ = EnumImpl::from_trait(data, &trait_, None, parse_quote! {
110 trait Coroutine<R> {
111 type Yield;
112 type Return;
113 }
114 })
115 .build_impl();
116
117 let resume = data.variant_idents().zip(data.field_types()).map(|(v, ty)| {
118 quote! {
119 #ident::#v(x) => <#ty as #trait_<R>>::resume(#pin::new_unchecked(x), arg),
120 }
121 });
122 impl_.items.push(parse_quote! {
123 #[inline]
124 fn resume(
125 self: #pin<&mut Self>,
126 arg: R,
127 ) -> ::core::ops::CoroutineState<Self::Yield, Self::Return> {
128 unsafe {
129 match self.get_unchecked_mut() { #(#resume)* }
130 }
131 }
132 });
133
134 Ok(impl_.into_token_stream())
135 }
136}
137
138#[cfg(feature = "fn_traits")]
139pub(crate) mod fn_ {
140 use syn::TypeParam;
141
142 use crate::derive::prelude::*;
143
144 pub(crate) const NAME: &[&str] = &["Fn"];
145
146 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
147 let trait_path = quote!(::core::ops::Fn);
148 let trait_ = quote!(#trait_path(__T) -> __U);
149 let mut impl_ = EnumImpl::new(data);
150
151 impl_.set_trait(parse_quote!(#trait_path<(__T,)>));
152 impl_.push_generic_param(TypeParam::from(format_ident!("__T")).into());
153 impl_.push_generic_param(TypeParam::from(format_ident!("__U")).into());
154
155 data.field_types().for_each(|f| impl_.push_where_predicate(parse_quote!(#f: #trait_)));
156
157 impl_.push_method(parse_quote! {
158 #[inline]
159 extern "rust-call" fn call(&self, args: (__T,)) -> Self::Output;
160 });
161
162 Ok(impl_.build())
163 }
164}
165
166#[cfg(feature = "fn_traits")]
167pub(crate) mod fn_mut {
168 use syn::TypeParam;
169
170 use crate::derive::prelude::*;
171
172 pub(crate) const NAME: &[&str] = &["FnMut"];
173
174 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
175 let trait_path = quote!(::core::ops::FnMut);
176 let trait_ = quote!(#trait_path(__T) -> __U);
177 let mut impl_ = EnumImpl::new(data);
178
179 impl_.set_trait(parse_quote!(#trait_path<(__T,)>));
180 impl_.push_generic_param(TypeParam::from(format_ident!("__T")).into());
181 impl_.push_generic_param(TypeParam::from(format_ident!("__U")).into());
182
183 data.field_types().for_each(|f| impl_.push_where_predicate(parse_quote!(#f: #trait_)));
184
185 impl_.push_method(parse_quote! {
186 #[inline]
187 extern "rust-call" fn call_mut(&mut self, args: (__T,)) -> Self::Output;
188 });
189
190 Ok(impl_.build())
191 }
192}
193
194#[cfg(feature = "fn_traits")]
195pub(crate) mod fn_once {
196 use syn::TypeParam;
197
198 use crate::derive::prelude::*;
199
200 pub(crate) const NAME: &[&str] = &["FnOnce"];
201
202 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
203 let trait_path = quote!(::core::ops::FnOnce);
204 let trait_ = quote!(#trait_path(__T) -> __U);
205 let mut impl_ = EnumImpl::new(data);
206
207 impl_.set_trait(parse_quote!(#trait_path<(__T,)>));
208 impl_.push_generic_param(TypeParam::from(format_ident!("__T")).into());
209 impl_.push_generic_param(TypeParam::from(format_ident!("__U")).into());
210
211 data.field_types().for_each(|f| impl_.push_where_predicate(parse_quote!(#f: #trait_)));
212
213 impl_.append_items_from_trait(parse_quote! {
214 trait FnOnce {
215 type Output;
216 #[inline]
217 extern "rust-call" fn call_once(self, args: (__T,)) -> Self::Output;
218 }
219 });
220
221 Ok(impl_.build())
222 }
223}
224