1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3#[cfg(feature = "ops")]
4pub(crate) mod deref {
5 use crate::derive::*;
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::*;
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::*;
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::*;
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::*;
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 quote::ToTokens;
100
101 use crate::derive::*;
102
103 pub(crate) const NAME: &[&str] = &["Coroutine"];
104
105 pub(crate) fn derive(cx: &Context, data: &Data) -> Result<TokenStream> {
106 cx.needs_pin_projection();
107
108 let ident = &data.ident;
109 let pin = quote!(::core::pin::Pin);
110 let trait_ = parse_quote!(::core::ops::Coroutine);
111 let mut impl_ = EnumImpl::from_trait(data, &trait_, None, parse_quote! {
112 trait Coroutine<R> {
113 type Yield;
114 type Return;
115 }
116 })
117 .build_impl();
118
119 let resume = data.variant_idents().zip(data.field_types()).map(|(v, ty)| {
120 quote! {
121 #ident::#v(x) => <#ty as #trait_<R>>::resume(#pin::new_unchecked(x), arg),
122 }
123 });
124 impl_.items.push(parse_quote! {
125 #[inline]
126 fn resume(
127 self: #pin<&mut Self>,
128 arg: R,
129 ) -> ::core::ops::CoroutineState<Self::Yield, Self::Return> {
130 unsafe {
131 match self.get_unchecked_mut() { #(#resume)* }
132 }
133 }
134 });
135
136 Ok(impl_.into_token_stream())
137 }
138}
139
140#[cfg(feature = "fn_traits")]
141pub(crate) mod fn_ {
142 use derive_utils::EnumImpl;
143 use syn::TypeParam;
144
145 use crate::derive::*;
146
147 pub(crate) const NAME: &[&str] = &["Fn"];
148
149 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
150 let trait_path = quote!(::core::ops::Fn);
151 let trait_ = quote!(#trait_path(__T) -> __U);
152 let mut impl_ = EnumImpl::new(data);
153
154 impl_.set_trait(parse_quote!(#trait_path<(__T,)>));
155 impl_.push_generic_param(TypeParam::from(format_ident!("__T")).into());
156 impl_.push_generic_param(TypeParam::from(format_ident!("__U")).into());
157
158 data.field_types().for_each(|f| impl_.push_where_predicate(parse_quote!(#f: #trait_)));
159
160 impl_.push_method(parse_quote! {
161 #[inline]
162 extern "rust-call" fn call(&self, args: (__T,)) -> Self::Output;
163 });
164
165 Ok(impl_.build())
166 }
167}
168
169#[cfg(feature = "fn_traits")]
170pub(crate) mod fn_mut {
171 use derive_utils::EnumImpl;
172 use syn::TypeParam;
173
174 use crate::derive::*;
175
176 pub(crate) const NAME: &[&str] = &["FnMut"];
177
178 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
179 let trait_path = quote!(::core::ops::FnMut);
180 let trait_ = quote!(#trait_path(__T) -> __U);
181 let mut impl_ = EnumImpl::new(data);
182
183 impl_.set_trait(parse_quote!(#trait_path<(__T,)>));
184 impl_.push_generic_param(TypeParam::from(format_ident!("__T")).into());
185 impl_.push_generic_param(TypeParam::from(format_ident!("__U")).into());
186
187 data.field_types().for_each(|f| impl_.push_where_predicate(parse_quote!(#f: #trait_)));
188
189 impl_.push_method(parse_quote! {
190 #[inline]
191 extern "rust-call" fn call_mut(&mut self, args: (__T,)) -> Self::Output;
192 });
193
194 Ok(impl_.build())
195 }
196}
197
198#[cfg(feature = "fn_traits")]
199pub(crate) mod fn_once {
200 use derive_utils::EnumImpl;
201 use syn::TypeParam;
202
203 use crate::derive::*;
204
205 pub(crate) const NAME: &[&str] = &["FnOnce"];
206
207 pub(crate) fn derive(_cx: &Context, data: &Data) -> Result<TokenStream> {
208 let trait_path = quote!(::core::ops::FnOnce);
209 let trait_ = quote!(#trait_path(__T) -> __U);
210 let mut impl_ = EnumImpl::new(data);
211
212 impl_.set_trait(parse_quote!(#trait_path<(__T,)>));
213 impl_.push_generic_param(TypeParam::from(format_ident!("__T")).into());
214 impl_.push_generic_param(TypeParam::from(format_ident!("__U")).into());
215
216 data.field_types().for_each(|f| impl_.push_where_predicate(parse_quote!(#f: #trait_)));
217
218 impl_.append_items_from_trait(parse_quote! {
219 trait FnOnce {
220 type Output;
221 #[inline]
222 extern "rust-call" fn call_once(self, args: (__T,)) -> Self::Output;
223 }
224 });
225
226 Ok(impl_.build())
227 }
228}
229