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