-
Notifications
You must be signed in to change notification settings - Fork 350
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
David Barsky
committed
Jun 28, 2019
1 parent
f914c3f
commit c3fb792
Showing
19 changed files
with
3,347 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "lambda-attributes" | ||
version = "0.1.0" | ||
authors = ["David Barsky <[email protected]>"] | ||
edition = "2018" | ||
|
||
[lib] | ||
proc-macro = true | ||
|
||
[dependencies] | ||
syn = { version = "0.15.33", features = ["full"] } | ||
proc-macro2 = { version = "0.4.29", features = ["nightly"] } | ||
quote = "0.6.12" | ||
runtime = "0.3.0-alpha.5" | ||
bytes = "0.4.12" | ||
|
||
[dev-dependencies] | ||
runtime = "0.3.0-alpha.5" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
extern crate proc_macro; | ||
|
||
use proc_macro::TokenStream; | ||
use quote::quote_spanned; | ||
use syn::{spanned::Spanned, FnArg, ItemFn}; | ||
|
||
#[cfg(not(test))] | ||
#[proc_macro_attribute] | ||
pub fn lambda(_attr: TokenStream, item: TokenStream) -> TokenStream { | ||
let input = syn::parse_macro_input!(item as ItemFn); | ||
|
||
let ret = &input.decl.output; | ||
let name = &input.ident; | ||
let body = &input.block; | ||
let attrs = &input.attrs; | ||
let asyncness = &input.asyncness; | ||
let inputs = &input.decl.inputs; | ||
|
||
if name != "main" { | ||
let tokens = quote_spanned! { name.span() => | ||
compile_error!("only the main function can be tagged with #[lambda::main]"); | ||
}; | ||
return TokenStream::from(tokens); | ||
} | ||
|
||
if asyncness.is_none() { | ||
let tokens = quote_spanned! { input.span() => | ||
compile_error!("the async keyword is missing from the function declaration"); | ||
}; | ||
return TokenStream::from(tokens); | ||
} | ||
|
||
let result = match inputs.len() { | ||
1 => { | ||
let event = match inputs.first().unwrap().into_value() { | ||
FnArg::Captured(arg) => arg, | ||
_ => { | ||
let tokens = quote_spanned! { inputs.span() => | ||
compile_error!("fn main should take a fully formed argument"); | ||
}; | ||
return TokenStream::from(tokens); | ||
} | ||
}; | ||
let arg_name = &event.pat; | ||
let arg_type = &event.ty; | ||
|
||
quote_spanned! { input.span() => | ||
#(#attrs)* | ||
#asyncness fn main() { | ||
async fn actual(#arg_name: #arg_type, ctx: Option<lambda::LambdaCtx>) #ret { | ||
#body | ||
} | ||
let f = lambda::handler_fn(actual); | ||
|
||
lambda::run(f).await.unwrap(); | ||
} | ||
} | ||
} | ||
2 => { | ||
let event = match inputs.first().unwrap().into_value() { | ||
FnArg::Captured(arg) => arg, | ||
_ => { | ||
let tokens = quote_spanned! { inputs.span() => | ||
compile_error!("fn main should take a fully formed argument"); | ||
}; | ||
return TokenStream::from(tokens); | ||
} | ||
}; | ||
let ctx = match &inputs[1] { | ||
FnArg::Captured(arg) => arg, | ||
_ => { | ||
let tokens = quote_spanned! { inputs.span() => | ||
compile_error!("fn main should take a fully formed argument"); | ||
}; | ||
return TokenStream::from(tokens); | ||
} | ||
}; | ||
let arg_name = &event.pat; | ||
let arg_type = &event.ty; | ||
let ctx_name = &ctx.pat; | ||
let ctx_type = &ctx.ty; | ||
quote_spanned! { input.span() => | ||
#(#attrs)* | ||
#asyncness fn main() { | ||
async fn actual(#arg_name: #arg_type, #ctx_name: Option<#ctx_type>) #ret { | ||
let #ctx_name = #ctx_name.unwrap(); | ||
#body | ||
} | ||
let f = lambda::handler_fn(actual); | ||
|
||
lambda::run(f).await.unwrap(); | ||
} | ||
} | ||
} | ||
_ => { | ||
let tokens = quote_spanned! { inputs.span() => | ||
compile_error!("The #[lambda] macro can accept one or two arguments."); | ||
}; | ||
return TokenStream::from(tokens); | ||
} | ||
}; | ||
|
||
result.into() | ||
} |
Oops, something went wrong.