auto_enums/derive/core/
ops.rs

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}