1 | // SPDX-License-Identifier: Apache-2.0 OR MIT |
2 | |
3 | use quote::ToTokens; |
4 | |
5 | use crate::derive::*; |
6 | |
7 | pub(crate) const NAME: &[&str] = &["Future" ]; |
8 | |
9 | pub(crate) fn derive(cx: &Context, data: &Data) -> Result<TokenStream> { |
10 | cx.needs_pin_projection(); |
11 | |
12 | let ident = &data.ident; |
13 | let pin = quote!(::core::pin::Pin); |
14 | let trait_ = parse_quote!(::core::future::Future); |
15 | let mut impl_ = EnumImpl::from_trait(data, &trait_, None, parse_quote! { |
16 | trait Future { |
17 | type Output; |
18 | } |
19 | }) |
20 | .build_impl(); |
21 | |
22 | let poll = data.variant_idents().zip(data.field_types()).map(|(v, ty)| { |
23 | quote! { |
24 | #ident::#v(x) => <#ty as #trait_>::poll(#pin::new_unchecked(x), cx), |
25 | } |
26 | }); |
27 | impl_.items.push(parse_quote! { |
28 | #[inline] |
29 | fn poll( |
30 | self: #pin<&mut Self>, |
31 | cx: &mut ::core::task::Context<'_>, |
32 | ) -> ::core::task::Poll<Self::Output> { |
33 | unsafe { |
34 | match self.get_unchecked_mut() { #(#poll)* } |
35 | } |
36 | } |
37 | }); |
38 | |
39 | Ok(impl_.into_token_stream()) |
40 | } |
41 | |