1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
extern crate proc_macro; #[macro_use] extern crate syn; #[macro_use] extern crate quote; extern crate proc_macro2; use proc_macro::TokenStream; use syn::export::ToTokens; use syn::ItemFn; #[proc_macro_attribute] pub fn osaka(_args: TokenStream, input: TokenStream) -> TokenStream { let mut f = parse_macro_input!(input as ItemFn); let output = match f.decl.output.clone() { syn::ReturnType::Default => quote! {()}, syn::ReturnType::Type(_, t) => quote! {#t}, }; f.decl.output = match syn::parse((quote! { -> osaka::Task<#output> }).into(), ) { Ok(v) => v, Err(e) => return e.to_compile_error().into(), }; let oblock = f.block; f.block = match syn::parse( (quote! {{ use std::ops::Generator; use std::pin::Pin; let mut l = move||{ #oblock }; let a = match Pin::new(&mut l).resume() { std::ops::GeneratorState::Complete(y) => { return osaka::Task::immediate(y); } std::ops::GeneratorState::Yielded(y) => { y } }; osaka::Task::new(Box::new(l),a) }}) .into(), ) { Ok(v) => v, Err(e) => return e.to_compile_error().into(), }; f.into_token_stream().into() }