use resource::{Arg, Attributes, Signature, TyTree};
use proc_macro2::TokenStream;
use syn;
#[derive(Debug)]
pub(crate) struct Route {
pub index: usize,
sig: Signature,
pub attributes: Attributes,
}
impl Route {
pub fn new(index: usize, sig: Signature, attributes: Attributes) -> Self {
Route {
index,
sig,
attributes,
}
}
pub fn ident(&self) -> &syn::Ident {
self.sig.ident()
}
pub fn args(&self) -> &[Arg] {
self.sig.args()
}
pub fn is_async(&self) -> bool {
self.sig.is_async()
}
pub fn template(&self) -> Option<&str> {
self.attributes.template()
}
pub fn build_route(&self, destination: TokenStream) -> TokenStream {
let method = self.attributes.method_expr();
let path = self.attributes.path_expr();
quote! {
.insert({
__tw::routing::Route::new(#destination)
.method(#method)
.path(#path)
})
}
}
pub fn dispatch_fn(&self) -> TokenStream {
TyTree::new(self.args())
.extract_args()
}
pub fn dispatch(&self) -> TokenStream {
let args_outer = self.sig.args().iter().map(|arg| {
let index = syn::Index::from(arg.index);
quote! { __tw::extract::ExtractFuture::extract(args.#index) }
});
let args_inner = self.sig.args().iter().map(|arg| {
let index = syn::Index::from(arg.index);
quote! { args.#index }
});
let body = self.sig.dispatch(
quote!(self.inner),
args_inner);
quote! {
let args = args.into_inner();
let args = (#(#args_outer,)*);
#body
}
}
pub fn handler_args_ty(&self) -> TokenStream {
TyTree::new(self.args())
.extract_args_ty()
}
pub fn future_ty(&self) -> TokenStream {
self.sig.future_ty()
}
}