diff --git a/gotham_restful/Cargo.toml b/gotham_restful/Cargo.toml index 2412749..1b9114b 100644 --- a/gotham_restful/Cargo.toml +++ b/gotham_restful/Cargo.toml @@ -21,6 +21,7 @@ failure = "0.1.6" futures = "0.1.29" gotham = "0.4" gotham_derive = "0.4" +gotham_middleware_diesel = { version = "0.1", optional = true } gotham_restful_derive = { version = "0.0.1" } hyper = "0.12.35" indexmap = { version = "1.3.0", optional = true } @@ -36,4 +37,5 @@ thiserror = "1" [features] default = [] +database = ["gotham_restful_derive/database", "gotham_middleware_diesel"] openapi = ["gotham_restful_derive/openapi", "indexmap", "log", "openapiv3"] diff --git a/gotham_restful/src/lib.rs b/gotham_restful/src/lib.rs index 1a3beb8..d5dc50c 100644 --- a/gotham_restful/src/lib.rs +++ b/gotham_restful/src/lib.rs @@ -122,6 +122,8 @@ pub use gotham_restful_derive::*; #[doc(hidden)] pub mod export { + #[cfg(feature = "database")] + pub use gotham_middleware_diesel::Repo; #[cfg(feature = "openapi")] pub use indexmap::IndexMap; #[cfg(feature = "openapi")] diff --git a/gotham_restful_derive/Cargo.toml b/gotham_restful_derive/Cargo.toml index bb0640f..6f07807 100644 --- a/gotham_restful_derive/Cargo.toml +++ b/gotham_restful_derive/Cargo.toml @@ -21,8 +21,9 @@ codecov = { repository = "msrd0/gotham-restful", branch = "master", service = "g heck = "0.3.1" proc-macro2 = "1.0.6" quote = "1.0.2" -syn = { version = "1.0.7", features = ["extra-traits", "full"] } +syn = { version = "1.0.13", features = ["extra-traits", "full"] } [features] -default = ["openapi"] +default = [] +database = [] openapi = [] diff --git a/gotham_restful_derive/src/method.rs b/gotham_restful_derive/src/method.rs index b8c9962..6a42f6c 100644 --- a/gotham_restful_derive/src/method.rs +++ b/gotham_restful_derive/src/method.rs @@ -107,11 +107,29 @@ pub fn expand_method(method : Method, attrs : TokenStream, item : TokenStream) - }, FnArg::Receiver(_) => panic!("didn't expect self parameter") }).collect(); - let mut generics : Vec = args.iter().skip(1).map(|(_, ty)| quote!(#ty)).collect(); + let args_state = args.iter().map(|(pat, _)| pat).nth(0).expect("state parameter is required"); + let args_conn = if cfg!(feature = "database") { + args.iter().filter(|(pat, _)| pat.to_string() == "conn").nth(0) + } else { None }; + let mut generics : Vec = args.iter().skip(1) + .filter(|(pat, _)| Some(pat.to_string()) != args_conn.map(|(pat, _)| pat.to_string())) + .map(|(_, ty)| quote!(#ty)).collect(); generics.push(quote!(#ret)); - let args_def : Vec = args.iter().map(|(pat, ty)| quote!(#pat : #ty)).collect(); + let args_def : Vec = args.iter() + .filter(|(pat, _)| Some(pat.to_string()) != args_conn.map(|(pat, _)| pat.to_string())) + .map(|(pat, ty)| quote!(#pat : #ty)).collect(); let args_pass : Vec = args.iter().map(|(pat, _)| quote!(#pat)).collect(); - let block = if is_no_content { quote!(#fun_ident(#(#args_pass),*); Default::default()) } else { quote!(#fun_ident(#(#args_pass),*)) }; + let mut block = if is_no_content { quote!(#fun_ident(#(#args_pass),*); Default::default()) } else { quote!(#fun_ident(#(#args_pass),*)) }; + if /*cfg!(feature = "database") &&*/ let Some((conn_pat, conn_ty)) = args_conn // https://github.com/rust-lang/rust/issues/53667 + { + let repo_ident = format_ident!("{}_database_repo", conn_pat.to_string()); + block = quote! { + let #repo_ident = <#krate::export::Repo<#conn_ty>>::borrow_from(&#args_state).clone(); + #repo_ident.run(move |#conn_pat| { + #block + }).wait() + }; + } let output = quote! { #fun