2019-09-21 20:36:57 +00:00
|
|
|
use indexmap::IndexMap;
|
|
|
|
use devise::{Spanned, ext::TypeExt};
|
2018-09-20 04:47:58 +00:00
|
|
|
use quote::ToTokens;
|
|
|
|
|
2019-09-21 20:36:57 +00:00
|
|
|
use crate::syn::{self, Expr, Ident, LitStr, Path, Token, Type};
|
|
|
|
use crate::syn::parse::{self, Parse, ParseStream};
|
|
|
|
use crate::syn::punctuated::Punctuated;
|
2018-09-20 04:47:58 +00:00
|
|
|
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
use crate::http::{uri, uri::Origin, ext::IntoOwned};
|
2019-09-21 20:36:57 +00:00
|
|
|
use crate::proc_macro2::{TokenStream, Span};
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
use crate::proc_macro_ext::StringLit;
|
|
|
|
use crate::attribute::param::{Parameter, Dynamic};
|
|
|
|
use crate::name::Name;
|
2019-09-21 20:36:57 +00:00
|
|
|
|
|
|
|
// TODO(diag): Use 'Diagnostic' in place of syn::Error.
|
2018-09-20 04:47:58 +00:00
|
|
|
|
2018-12-05 12:20:22 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ArgExpr {
|
|
|
|
Expr(Expr),
|
|
|
|
Ignored(Token![_]),
|
|
|
|
}
|
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
#[derive(Debug)]
|
2018-10-04 09:00:04 +00:00
|
|
|
pub enum Arg {
|
2018-12-05 12:20:22 +00:00
|
|
|
Unnamed(ArgExpr),
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Named(Name, Ident, Token![=], ArgExpr),
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Args {
|
2018-10-04 09:00:04 +00:00
|
|
|
Unnamed(Punctuated<Arg, Token![,]>),
|
|
|
|
Named(Punctuated<Arg, Token![,]>),
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// For an invocation that looks like:
|
|
|
|
// uri!("/mount/point", this::route: e1, e2, e3);
|
|
|
|
// ^-------------| ^----------| ^---------|
|
|
|
|
// uri_params.mount_point | uri_params.arguments
|
|
|
|
// uri_params.route_path
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct UriParams {
|
2018-10-04 10:54:46 +00:00
|
|
|
pub mount_point: Option<Origin<'static>>,
|
2018-09-20 04:47:58 +00:00
|
|
|
pub route_path: Path,
|
2018-10-04 09:00:04 +00:00
|
|
|
pub arguments: Args,
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct FnArg {
|
|
|
|
pub ident: Ident,
|
|
|
|
pub ty: Type,
|
|
|
|
}
|
|
|
|
|
2018-10-04 09:00:04 +00:00
|
|
|
pub enum Validation<'a> {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
// Parameters that were ignored in a named argument setting.
|
|
|
|
NamedIgnored(Vec<&'a Dynamic>),
|
2018-09-20 04:47:58 +00:00
|
|
|
// Number expected, what we actually got.
|
|
|
|
Unnamed(usize, usize),
|
|
|
|
// (Missing, Extra, Duplicate)
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Named(Vec<&'a Name>, Vec<&'a Ident>, Vec<&'a Ident>),
|
2018-10-04 09:00:04 +00:00
|
|
|
// Everything is okay; here are the expressions in the route decl order.
|
2018-12-05 12:20:22 +00:00
|
|
|
Ok(Vec<&'a ArgExpr>)
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 09:00:04 +00:00
|
|
|
// This is invoked by Rocket itself. The `uri!` macro expands to a call to a
|
|
|
|
// route-specific macro which in-turn expands to a call to `internal_uri!`,
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
// passing along the user's parameters (`uri_params`) from the original `uri!`
|
|
|
|
// call. This is necessary so that we can converge the type information in the
|
|
|
|
// route (from the route-specific macro) with the user's parameters (by
|
|
|
|
// forwarding them to the internal_uri! call).
|
2018-10-04 09:00:04 +00:00
|
|
|
//
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
// `fn_args` are the URI arguments (excluding request guards and ignored path
|
|
|
|
// parts) from the original handler in the order they were declared in the URI
|
|
|
|
// (`<first>/<second>`). `route_uri` is the URI itself.
|
2018-10-04 09:00:04 +00:00
|
|
|
//
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
// internal_uri!("/<one>/<_>?lang=en&<two>", (one: ty, two: ty), $($tt)*);
|
|
|
|
// ^----/----^ ^-----\-----^ ^-------/------^ ^-----|
|
|
|
|
// path_params query_params fn_args uri_params
|
|
|
|
// ^------ route_uri ------^
|
2018-09-20 04:47:58 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct InternalUriParams {
|
2018-10-04 10:54:46 +00:00
|
|
|
pub route_uri: Origin<'static>,
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
pub mount_params: Vec<Parameter>,
|
|
|
|
pub path_params: Vec<Parameter>,
|
|
|
|
pub query_params: Vec<Parameter>,
|
2018-09-20 04:47:58 +00:00
|
|
|
pub fn_args: Vec<FnArg>,
|
|
|
|
pub uri_params: UriParams,
|
|
|
|
}
|
|
|
|
|
2018-12-05 12:20:22 +00:00
|
|
|
impl Parse for ArgExpr {
|
2019-06-13 01:59:25 +00:00
|
|
|
fn parse(input: ParseStream<'_>) -> parse::Result<Self> {
|
2018-12-05 12:20:22 +00:00
|
|
|
if input.peek(Token![_]) {
|
|
|
|
return Ok(ArgExpr::Ignored(input.parse::<Token![_]>()?));
|
|
|
|
}
|
|
|
|
|
|
|
|
input.parse::<Expr>().map(ArgExpr::Expr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
impl Parse for Arg {
|
2019-06-13 01:59:25 +00:00
|
|
|
fn parse(input: ParseStream<'_>) -> parse::Result<Self> {
|
2018-09-20 04:47:58 +00:00
|
|
|
let has_key = input.peek2(Token![=]);
|
|
|
|
if has_key {
|
|
|
|
let ident = input.parse::<Ident>()?;
|
2018-10-04 09:00:04 +00:00
|
|
|
let eq_token = input.parse::<Token![=]>()?;
|
2018-12-05 12:20:22 +00:00
|
|
|
let expr = input.parse::<ArgExpr>()?;
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Ok(Arg::Named(Name::from(&ident), ident, eq_token, expr))
|
2018-09-20 04:47:58 +00:00
|
|
|
} else {
|
2018-12-05 12:20:22 +00:00
|
|
|
let expr = input.parse::<ArgExpr>()?;
|
2018-09-20 04:47:58 +00:00
|
|
|
Ok(Arg::Unnamed(expr))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-04 09:00:04 +00:00
|
|
|
fn err<T, S: AsRef<str>>(span: Span, s: S) -> parse::Result<T> {
|
|
|
|
Err(parse::Error::new(span.into(), s.as_ref()))
|
|
|
|
}
|
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
impl Parse for UriParams {
|
|
|
|
// Parses the mount point, if any, route identifier, and arguments.
|
2019-06-13 01:59:25 +00:00
|
|
|
fn parse(input: ParseStream<'_>) -> parse::Result<Self> {
|
2018-09-20 04:47:58 +00:00
|
|
|
if input.is_empty() {
|
|
|
|
return Err(input.error("call to `uri!` cannot be empty"));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the mount point and suffixing ',', if any.
|
|
|
|
let mount_point = if input.peek(LitStr) {
|
|
|
|
let string = input.parse::<LitStr>()?;
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
let mount_point = Origin::parse_owned(string.value())
|
|
|
|
.map(|m| m.into_normalized())
|
|
|
|
.map_err(|_| {
|
|
|
|
// TODO(proc_macro): use error, add example as a help
|
|
|
|
parse::Error::new(string.span(), "invalid mount point; \
|
2018-10-04 10:54:46 +00:00
|
|
|
mount points must be static, absolute URIs: `/example`")
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
})?;
|
2018-10-04 09:00:04 +00:00
|
|
|
|
|
|
|
if !input.peek(Token![,]) && input.cursor().eof() {
|
2019-09-21 20:36:57 +00:00
|
|
|
return err(string.span(), "unexpected end of input: \
|
2018-10-04 09:00:04 +00:00
|
|
|
expected ',' followed by route path");
|
|
|
|
}
|
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
input.parse::<Token![,]>()?;
|
2018-10-04 10:54:46 +00:00
|
|
|
Some(mount_point)
|
2018-09-20 04:47:58 +00:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
// Parse the route identifier, which must always exist.
|
|
|
|
let route_path = input.parse::<Path>()?;
|
|
|
|
|
|
|
|
// If there are no arguments, finish early.
|
2018-10-04 09:00:04 +00:00
|
|
|
if !input.peek(Token![:]) && input.cursor().eof() {
|
|
|
|
let arguments = Args::Unnamed(Punctuated::new());
|
2018-09-20 04:47:58 +00:00
|
|
|
return Ok(Self { mount_point, route_path, arguments });
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse arguments
|
2018-10-04 09:00:04 +00:00
|
|
|
let colon = input.parse::<Token![:]>()?;
|
2018-09-20 04:47:58 +00:00
|
|
|
let arguments: Punctuated<Arg, Token![,]> = input.parse_terminated(Arg::parse)?;
|
|
|
|
|
|
|
|
// A 'colon' was used but there are no arguments.
|
|
|
|
if arguments.is_empty() {
|
2018-10-04 09:00:04 +00:00
|
|
|
return err(colon.span(), "expected argument list after `:`");
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that both types of arguments were not used at once.
|
|
|
|
let (mut homogeneous_args, mut prev_named) = (true, None);
|
|
|
|
for arg in &arguments {
|
|
|
|
match prev_named {
|
|
|
|
Some(prev_named) => homogeneous_args = prev_named == arg.is_named(),
|
|
|
|
None => prev_named = Some(arg.is_named()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !homogeneous_args {
|
2018-10-04 09:00:04 +00:00
|
|
|
return err(arguments.span(), "named and unnamed parameters cannot be mixed");
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
|
2018-10-04 09:00:04 +00:00
|
|
|
// Create the `Args` enum, which properly record one-kind-of-argument-ness.
|
|
|
|
let arguments = match prev_named {
|
|
|
|
Some(true) => Args::Named(arguments),
|
|
|
|
_ => Args::Unnamed(arguments)
|
2018-09-20 04:47:58 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Self { mount_point, route_path, arguments })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Parse for FnArg {
|
2019-06-13 01:59:25 +00:00
|
|
|
fn parse(input: ParseStream<'_>) -> parse::Result<FnArg> {
|
2018-09-20 04:47:58 +00:00
|
|
|
let ident = input.parse::<Ident>()?;
|
|
|
|
input.parse::<Token![:]>()?;
|
|
|
|
let mut ty = input.parse::<Type>()?;
|
|
|
|
ty.strip_lifetimes();
|
|
|
|
Ok(FnArg { ident, ty })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Parse for InternalUriParams {
|
2019-06-13 01:59:25 +00:00
|
|
|
fn parse(input: ParseStream<'_>) -> parse::Result<InternalUriParams> {
|
2018-10-04 10:54:46 +00:00
|
|
|
let route_uri_str = input.parse::<LitStr>()?;
|
2018-09-20 04:47:58 +00:00
|
|
|
input.parse::<Token![,]>()?;
|
|
|
|
|
2018-10-04 10:54:46 +00:00
|
|
|
// Validation should always succeed since this macro can only be called
|
|
|
|
// if the route attribute succeeded, implying a valid route URI.
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
let route_uri_str = StringLit::new(route_uri_str.value(), route_uri_str.span());
|
|
|
|
let route_uri = Origin::parse_route(&route_uri_str)
|
2020-07-29 23:38:24 +00:00
|
|
|
.map(|o| o.into_normalized().into_owned())
|
2018-10-04 10:54:46 +00:00
|
|
|
.map_err(|_| input.error("internal error: invalid route URI"))?;
|
|
|
|
|
2018-09-20 04:47:58 +00:00
|
|
|
let content;
|
|
|
|
syn::parenthesized!(content in input);
|
|
|
|
let fn_args: Punctuated<FnArg, Token![,]> = content.parse_terminated(FnArg::parse)?;
|
|
|
|
let fn_args = fn_args.into_iter().collect();
|
|
|
|
|
|
|
|
input.parse::<Token![,]>()?;
|
|
|
|
let uri_params = input.parse::<UriParams>()?;
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
|
|
|
|
// This span isn't right...we don't have the original span.
|
|
|
|
let span = route_uri_str.subspan(1..route_uri.path().len() + 1);
|
|
|
|
let mount_params = match uri_params.mount_point.as_ref() {
|
|
|
|
Some(mount) => Parameter::parse_many::<uri::Path>(mount.path().as_str(), span)
|
|
|
|
.map(|p| p.expect("internal error: invalid path parameter"))
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
None => vec![]
|
|
|
|
};
|
|
|
|
|
|
|
|
let path_params = Parameter::parse_many::<uri::Path>(route_uri.path().as_str(), span)
|
|
|
|
.map(|p| p.expect("internal error: invalid path parameter"))
|
|
|
|
.collect::<Vec<_>>();
|
|
|
|
|
|
|
|
let query_params = match route_uri.query() {
|
|
|
|
Some(query) => {
|
|
|
|
let i = route_uri.path().len() + 2;
|
|
|
|
let span = route_uri_str.subspan(i..(i + query.len()));
|
|
|
|
Parameter::parse_many::<uri::Query>(query.as_str(), span)
|
|
|
|
.map(|p| p.expect("internal error: invalid query parameter"))
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
}
|
|
|
|
None => vec![]
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(InternalUriParams { route_uri, mount_params, path_params, query_params, fn_args, uri_params })
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl InternalUriParams {
|
|
|
|
pub fn fn_args_str(&self) -> String {
|
|
|
|
self.fn_args.iter()
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
.map(|FnArg { ident, ty }| {
|
|
|
|
let ty = ty.with_stripped_lifetimes();
|
|
|
|
let ty_str = quote!(#ty).to_string();
|
|
|
|
let ty_str: String = ty_str.chars().filter(|c| !c.is_whitespace()).collect();
|
|
|
|
format!("{}: {}", ident, ty_str)
|
|
|
|
})
|
2018-09-20 04:47:58 +00:00
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.join(", ")
|
|
|
|
}
|
|
|
|
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
pub fn dynamic_path_params(&self) -> impl Iterator<Item = &Dynamic> + Clone {
|
|
|
|
self.path_params.iter()
|
|
|
|
.filter_map(|p| p.dynamic().or_else(|| p.ignored()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn dynamic_query_params(&self) -> impl Iterator<Item = &Dynamic> + Clone {
|
|
|
|
self.query_params.iter().filter_map(|p| p.dynamic())
|
|
|
|
}
|
|
|
|
|
2019-06-13 01:59:25 +00:00
|
|
|
pub fn validate(&self) -> Validation<'_> {
|
2018-10-04 09:00:04 +00:00
|
|
|
let args = &self.uri_params.arguments;
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
let all_params = self.dynamic_path_params().chain(self.dynamic_query_params());
|
2018-10-04 09:00:04 +00:00
|
|
|
match args {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Args::Unnamed(args) => {
|
|
|
|
let (expected, actual) = (all_params.count(), args.len());
|
|
|
|
let unnamed_args = args.iter().map(|arg| arg.unnamed());
|
|
|
|
match expected == actual {
|
|
|
|
true => Validation::Ok(unnamed_args.collect()),
|
|
|
|
false => Validation::Unnamed(expected, actual)
|
|
|
|
}
|
2018-10-04 09:00:04 +00:00
|
|
|
},
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Args::Named(args) => {
|
|
|
|
let ignored = all_params.clone().filter(|p| p.is_wild());
|
|
|
|
if ignored.clone().count() > 0 {
|
|
|
|
return Validation::NamedIgnored(ignored.collect());
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut params = all_params.map(|p| (&p.name, None))
|
|
|
|
.collect::<IndexMap<&Name, Option<&ArgExpr>>>();
|
2018-09-20 04:47:58 +00:00
|
|
|
|
|
|
|
let (mut extra, mut dup) = (vec![], vec![]);
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
let named_args = args.iter().map(|arg| arg.named());
|
|
|
|
for (name, ident, expr) in named_args {
|
2020-06-19 23:03:38 +00:00
|
|
|
match params.get_mut(name) {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Some(ref entry) if entry.is_some() => dup.push(ident),
|
2018-10-04 09:00:04 +00:00
|
|
|
Some(entry) => *entry = Some(expr),
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
None => extra.push(ident),
|
2018-09-20 04:47:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let (mut missing, mut exprs) = (vec![], vec![]);
|
|
|
|
for (name, expr) in params {
|
|
|
|
match expr {
|
|
|
|
Some(expr) => exprs.push(expr),
|
|
|
|
None => missing.push(name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (extra.len() + dup.len() + missing.len()) == 0 {
|
|
|
|
Validation::Ok(exprs)
|
|
|
|
} else {
|
|
|
|
Validation::Named(missing, extra, dup)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-04 09:00:04 +00:00
|
|
|
impl UriParams {
|
|
|
|
/// The Span to use when referring to all of the arguments.
|
|
|
|
pub fn args_span(&self) -> Span {
|
|
|
|
match self.arguments.num() {
|
|
|
|
0 => self.route_path.span(),
|
|
|
|
_ => self.arguments.span()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Arg {
|
|
|
|
fn is_named(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
Arg::Named(..) => true,
|
2018-12-05 12:20:22 +00:00
|
|
|
_ => false
|
2018-10-04 09:00:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-05 12:20:22 +00:00
|
|
|
fn unnamed(&self) -> &ArgExpr {
|
2018-10-04 09:00:04 +00:00
|
|
|
match self {
|
|
|
|
Arg::Unnamed(expr) => expr,
|
|
|
|
_ => panic!("Called Arg::unnamed() on an Arg::named!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
fn named(&self) -> (&Name, &Ident, &ArgExpr) {
|
2018-10-04 09:00:04 +00:00
|
|
|
match self {
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Arg::Named(name, ident, _, expr) => (name, ident, expr),
|
2018-10-04 09:00:04 +00:00
|
|
|
_ => panic!("Called Arg::named() on an Arg::Unnamed!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Args {
|
|
|
|
fn num(&self) -> usize {
|
|
|
|
match self {
|
|
|
|
Args::Named(inner) | Args::Unnamed(inner) => inner.len(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-05 12:20:22 +00:00
|
|
|
impl ArgExpr {
|
|
|
|
pub fn as_expr(&self) -> Option<&Expr> {
|
|
|
|
match self {
|
|
|
|
ArgExpr::Expr(expr) => Some(expr),
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn unwrap_expr(&self) -> &Expr {
|
|
|
|
match self {
|
|
|
|
ArgExpr::Expr(expr) => expr,
|
|
|
|
_ => panic!("Called ArgExpr::expr() on ArgExpr::Ignored!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToTokens for ArgExpr {
|
2019-09-21 20:36:57 +00:00
|
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
2018-12-05 12:20:22 +00:00
|
|
|
match self {
|
|
|
|
ArgExpr::Expr(e) => e.to_tokens(tokens),
|
|
|
|
ArgExpr::Ignored(e) => e.to_tokens(tokens)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-10-04 09:00:04 +00:00
|
|
|
|
|
|
|
impl ToTokens for Arg {
|
2019-09-21 20:36:57 +00:00
|
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
2018-10-04 09:00:04 +00:00
|
|
|
match self {
|
|
|
|
Arg::Unnamed(e) => e.to_tokens(tokens),
|
Revamp codegen, fixing inconscpicuous bugs.
This commit completely revamps the way that codegen handles route URI
"parameters". The changes are largely internal. In summary, codegen code
is better organized, better written, and less subject to error.
There are three breaking changes:
* `path` is now `uri` in `route` attribute: `#[route(GET, path = "..")]`
becomes `#[route(GET, uri = "..")]`.
* the order of execution for path and query guards relative to
each-other is now unspecified
* URI normalization now normalizes the query part as well.
Several error messages were improved. A couple of bugs were fixed:
* Prior to this commit, Rocket would optimistically try to parse every
segment of a URI as an ident, in case one was needed in the future.
A bug in rustc results in codegen "panicking" if the segment
couldn't _lex_ as an ident. This panic didn't manifest until far
after expansion, unfortunately. This wasn't a problem before as we
only allowed ident-like segments (ASCII), but now that we allow any
UTF-8, the bug surfaced. This was fixed by never attempting to parse
non-idents as idents.
* Prior to this commit, it was impossible to generate typed URIs for
paths that ignored path parameters via the recently added syntax
`<_>`: the macro would panic. This was fixed by, well, handling
these ignored parameters.
Some minor additions:
* Added `RawStr::find()`, expanding its `Pattern`-based API.
* Added an internal mechanism to dynamically determine if a `UriPart`
is `Path` or `Query`.
2021-03-02 12:01:33 +00:00
|
|
|
Arg::Named(_, ident, eq, expr) => {
|
|
|
|
ident.to_tokens(tokens);
|
|
|
|
eq.to_tokens(tokens);
|
|
|
|
expr.to_tokens(tokens);
|
2020-11-03 08:44:28 +00:00
|
|
|
}
|
2018-10-04 09:00:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToTokens for Args {
|
2019-09-21 20:36:57 +00:00
|
|
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
2018-10-04 09:00:04 +00:00
|
|
|
match self {
|
|
|
|
Args::Unnamed(e) | Args::Named(e) => e.to_tokens(tokens)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|