2019-09-21 20:36:57 +00:00
|
|
|
use devise::Result;
|
2018-09-16 07:44:47 +00:00
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
use crate::syn::{Path, punctuated::Punctuated, parse::Parser, Token};
|
|
|
|
use crate::proc_macro2::TokenStream;
|
2020-10-13 05:11:44 +00:00
|
|
|
use crate::syn::spanned::Spanned;
|
2018-09-16 07:44:47 +00:00
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
mod uri;
|
|
|
|
mod uri_parsing;
|
2020-02-15 11:43:47 +00:00
|
|
|
mod test_guide;
|
2018-09-20 04:47:58 +00:00
|
|
|
|
2020-10-13 05:11:44 +00:00
|
|
|
fn struct_maker_vec(
|
2019-09-21 20:36:57 +00:00
|
|
|
input: proc_macro::TokenStream,
|
2020-10-13 05:11:44 +00:00
|
|
|
ty: TokenStream,
|
2019-09-21 20:36:57 +00:00
|
|
|
) -> Result<TokenStream> {
|
2020-10-13 05:11:44 +00:00
|
|
|
define_vars_and_mods!(_Vec);
|
2018-09-16 07:44:47 +00:00
|
|
|
|
2020-10-13 05:11:44 +00:00
|
|
|
// Parse a comma-separated list of paths.
|
|
|
|
let paths = <Punctuated<Path, Token![,]>>::parse_terminated.parse(input)?;
|
|
|
|
let exprs = paths.iter()
|
|
|
|
.map(|path| quote_spanned!(path.span() => {
|
|
|
|
let ___struct = #path {};
|
|
|
|
let ___item: #ty = ___struct.into();
|
|
|
|
___item
|
|
|
|
}));
|
2018-09-16 07:44:47 +00:00
|
|
|
|
2020-10-13 05:11:44 +00:00
|
|
|
Ok(quote!({
|
|
|
|
let ___vec: #_Vec<#ty> = vec![#(#exprs),*];
|
|
|
|
___vec
|
|
|
|
}))
|
2018-09-16 07:44:47 +00:00
|
|
|
}
|
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
pub fn routes_macro(input: proc_macro::TokenStream) -> TokenStream {
|
2020-10-13 05:11:44 +00:00
|
|
|
struct_maker_vec(input, quote!(::rocket::Route))
|
|
|
|
.unwrap_or_else(|diag| diag.emit_as_expr_tokens())
|
2018-09-16 07:44:47 +00:00
|
|
|
}
|
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
pub fn catchers_macro(input: proc_macro::TokenStream) -> TokenStream {
|
2020-10-13 05:11:44 +00:00
|
|
|
struct_maker_vec(input, quote!(::rocket::Catcher))
|
|
|
|
.unwrap_or_else(|diag| diag.emit_as_expr_tokens())
|
2018-09-16 07:44:47 +00:00
|
|
|
}
|
2018-09-20 04:47:58 +00:00
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
pub fn uri_macro(input: proc_macro::TokenStream) -> TokenStream {
|
|
|
|
uri::_uri_macro(input.into())
|
2020-07-21 17:23:59 +00:00
|
|
|
.unwrap_or_else(|diag| diag.emit_as_expr_tokens())
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
pub fn uri_internal_macro(input: proc_macro::TokenStream) -> TokenStream {
|
Use 'Option', 'Result' directly in 'uri!' query.
Prior to this commit, the conversion 'T -> Option<T>' was applied in
both the path and query parts of a URI in the 'uri' macro via the
'FromUriParam' trait with no implementation for 'Option<T>' directly.
This meant that it was impossible to directly render an 'Option<T>'.
This was exactly desired for the path part, where rendering a 'None'
would yield an incorrect URI, but the restriction was too strict for the
query part, where a 'None' is entirely valid. This commit makes changes
the conversion so that it only applied to path parts and adds the
identity conversions for 'Option<T>' and 'Result<T, E>' for query parts.
The side effect is a breaking change: due to conflicting impls, the 'T'
to 'Option<T>' conversion was removed for query parts. Thus, all 'uri!'
query route arguments of type 'Option' or 'Result' must now be wrapped
in 'Some' or 'Ok'. Due to new 'Option<T> <-> Result<T, E>' conversions,
either 'Some' _and_ 'Ok' work in both contexts.
Closes #1420.
2020-11-01 18:30:30 +00:00
|
|
|
// FIXME: Ideally we would generate an `Origin::dummy()` so that we don't
|
|
|
|
// assist in propoagate further errors. Alas, we can't set the span to the
|
|
|
|
// invocation of `uri!` without access to `span.parent()`, and
|
|
|
|
// `Span::call_site()` here points to the `#[route]`, immediate caller,
|
|
|
|
// generate a rather confusing error message when there's a type-mismatch.
|
|
|
|
// uri::_uri_internal_macro(input.into())
|
|
|
|
// .unwrap_or_else(|diag| diag.emit_as_expr_tokens_or(quote_spanned! { span =>
|
|
|
|
// rocket::http::uri::Origin::dummy()
|
|
|
|
// }))
|
|
|
|
|
|
|
|
uri::_uri_internal_macro(input.into())
|
|
|
|
.unwrap_or_else(|diag| diag.emit_as_expr_tokens())
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
2020-02-15 11:43:47 +00:00
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
pub fn guide_tests_internal(input: proc_macro::TokenStream) -> TokenStream {
|
2020-02-15 11:43:47 +00:00
|
|
|
test_guide::_macro(input)
|
2020-07-21 17:23:59 +00:00
|
|
|
.unwrap_or_else(|diag| diag.emit_as_item_tokens())
|
2020-02-15 11:43:47 +00:00
|
|
|
}
|