2018-09-16 07:44:47 +00:00
|
|
|
use proc_macro::TokenStream;
|
|
|
|
use proc_macro2::TokenStream as TokenStream2;
|
|
|
|
|
2018-10-29 04:09:04 +00:00
|
|
|
use devise::{syn, Spanned, Result};
|
2018-09-16 07:44:47 +00:00
|
|
|
use self::syn::{Path, punctuated::Punctuated, parse::Parser, token::Comma};
|
|
|
|
use syn_ext::{IdentExt, syn_to_diag};
|
2018-09-20 04:14:30 +00:00
|
|
|
use {ROUTE_STRUCT_PREFIX, CATCH_STRUCT_PREFIX};
|
2018-09-16 07:44:47 +00:00
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
mod uri;
|
|
|
|
mod uri_parsing;
|
|
|
|
|
2018-10-04 09:00:04 +00:00
|
|
|
crate fn prefix_last_segment(path: &mut Path, prefix: &str) {
|
|
|
|
let mut last_seg = path.segments.last_mut().expect("syn::Path has segments");
|
|
|
|
last_seg.value_mut().ident = last_seg.value().ident.prepend(prefix);
|
|
|
|
}
|
|
|
|
|
2018-09-20 04:14:30 +00:00
|
|
|
fn _prefixed_vec(
|
|
|
|
prefix: &str,
|
|
|
|
input: TokenStream,
|
|
|
|
ty: &TokenStream2
|
|
|
|
) -> Result<TokenStream2> {
|
2018-09-16 07:44:47 +00:00
|
|
|
// Parse a comma-separated list of paths.
|
|
|
|
let mut paths = <Punctuated<Path, Comma>>::parse_terminated
|
|
|
|
.parse(input)
|
|
|
|
.map_err(syn_to_diag)?;
|
|
|
|
|
|
|
|
// Prefix the last segment in each path with `prefix`.
|
2018-10-04 09:00:04 +00:00
|
|
|
paths.iter_mut().for_each(|p| prefix_last_segment(p, prefix));
|
2018-09-16 07:44:47 +00:00
|
|
|
|
|
|
|
// Return a `vec!` of the prefixed, mapped paths.
|
|
|
|
let prefixed_mapped_paths = paths.iter()
|
|
|
|
.map(|path| quote_spanned!(path.span().into() => #ty::from(&#path)));
|
|
|
|
|
|
|
|
Ok(quote!(vec![#(#prefixed_mapped_paths),*]))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn prefixed_vec(prefix: &str, input: TokenStream, ty: TokenStream2) -> TokenStream {
|
|
|
|
let vec = _prefixed_vec(prefix, input, &ty)
|
|
|
|
.map_err(|diag| diag.emit())
|
|
|
|
.unwrap_or_else(|_| quote!(vec![]));
|
|
|
|
|
|
|
|
quote!({
|
|
|
|
let __vector: Vec<#ty> = #vec;
|
|
|
|
__vector
|
|
|
|
}).into()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn routes_macro(input: TokenStream) -> TokenStream {
|
|
|
|
prefixed_vec(ROUTE_STRUCT_PREFIX, input, quote!(::rocket::Route))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn catchers_macro(input: TokenStream) -> TokenStream {
|
|
|
|
prefixed_vec(CATCH_STRUCT_PREFIX, input, quote!(::rocket::Catcher))
|
|
|
|
}
|
2018-09-20 04:47:58 +00:00
|
|
|
|
|
|
|
pub fn uri_macro(input: TokenStream) -> TokenStream {
|
|
|
|
uri::_uri_macro(input)
|
|
|
|
.map_err(|diag| diag.emit())
|
|
|
|
.unwrap_or_else(|_| quote!(()).into())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn uri_internal_macro(input: TokenStream) -> TokenStream {
|
|
|
|
uri::_uri_internal_macro(input)
|
|
|
|
.map_err(|diag| diag.emit())
|
|
|
|
.unwrap_or_else(|_| quote!(()).into())
|
|
|
|
}
|