Skip to content

Commit 35669cc

Browse files
authored
Merge branch 'SergioBenitez:master' into fix_issue_1224
2 parents 2a2272e + 1563718 commit 35669cc

File tree

96 files changed

+1002
-593
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+1002
-593
lines changed

contrib/db_pools/codegen/src/database.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub fn derive_database(input: TokenStream) -> TokenStream {
6767
) -> rocket::request::Outcome<Self, Self::Error> {
6868
match #db_ty::fetch(req.rocket()) {
6969
Some(db) => rocket::outcome::Outcome::Success(db),
70-
None => rocket::outcome::Outcome::Failure((
70+
None => rocket::outcome::Outcome::Error((
7171
rocket::http::Status::InternalServerError, ()))
7272
}
7373
}

contrib/db_pools/lib/src/database.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ pub struct Initializer<D: Database>(Option<&'static str>, PhantomData<fn() -> D>
164164
/// [`connect_timeout`](crate::Config::connect_timeout) seconds.
165165
/// * If the `Initializer` fairing was _not_ attached, the guard _fails_ with
166166
/// status `InternalServerError`. A [`Sentinel`] guards this condition, and so
167-
/// this type of failure is unlikely to occur. A `None` error is returned.
167+
/// this type of error is unlikely to occur. A `None` error is returned.
168168
/// * If a connection is not available within `connect_timeout` seconds or
169169
/// another error occurs, the guard _fails_ with status `ServiceUnavailable`
170170
/// and the error is returned in `Some`.
@@ -288,9 +288,9 @@ impl<'r, D: Database> FromRequest<'r> for Connection<D> {
288288
match D::fetch(req.rocket()) {
289289
Some(db) => match db.get().await {
290290
Ok(conn) => Outcome::Success(Connection(conn)),
291-
Err(e) => Outcome::Failure((Status::ServiceUnavailable, Some(e))),
291+
Err(e) => Outcome::Error((Status::ServiceUnavailable, Some(e))),
292292
},
293-
None => Outcome::Failure((Status::InternalServerError, None)),
293+
None => Outcome::Error((Status::InternalServerError, None)),
294294
}
295295
}
296296
}

contrib/dyn_templates/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ tera = ["tera_"]
1717
handlebars = ["handlebars_"]
1818

1919
[dependencies]
20-
glob = "0.3"
21-
notify = "5.0.0"
20+
walkdir = "2.4"
21+
notify = "6"
2222
normpath = "1"
2323

2424
[dependencies.rocket]

contrib/dyn_templates/src/context.rs

+22-11
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ impl Context {
2626
/// template engine, and store all of the initialized state in a `Context`
2727
/// structure, which is returned if all goes well.
2828
pub fn initialize(root: &Path, callback: &Callback) -> Option<Context> {
29+
fn is_file_with_ext(entry: &walkdir::DirEntry, ext: &str) -> bool {
30+
let is_file = entry.file_type().is_file();
31+
let has_ext = entry.path().extension().map_or(false, |e| e == ext);
32+
is_file && has_ext
33+
}
34+
2935
let root = match root.normalize() {
3036
Ok(root) => root.into_path_buf(),
3137
Err(e) => {
@@ -35,18 +41,23 @@ impl Context {
3541
};
3642

3743
let mut templates: HashMap<String, TemplateInfo> = HashMap::new();
38-
for ext in Engines::ENABLED_EXTENSIONS {
39-
let mut glob_path = root.join("**").join("*");
40-
glob_path.set_extension(ext);
41-
let glob_path = glob_path.to_str().expect("valid glob path string");
44+
for &ext in Engines::ENABLED_EXTENSIONS {
45+
for entry in walkdir::WalkDir::new(&root).follow_links(true) {
46+
let entry = match entry {
47+
Ok(entry) if is_file_with_ext(&entry, ext) => entry,
48+
Ok(_) | Err(_) => continue,
49+
};
4250

43-
for path in glob::glob(glob_path).unwrap().filter_map(Result::ok) {
44-
let (name, data_type_str) = split_path(&root, &path);
51+
let (name, data_type_str) = split_path(&root, entry.path());
4552
if let Some(info) = templates.get(&*name) {
46-
warn_!("Template name '{}' does not have a unique path.", name);
47-
info_!("Existing path: {:?}", info.path);
48-
info_!("Additional path: {:?}", path);
49-
warn_!("Using existing path for template '{}'.", name);
53+
warn_!("Template name '{}' does not have a unique source.", name);
54+
match info.path {
55+
Some(ref path) => info_!("Existing path: {:?}", path),
56+
None => info_!("Existing Content-Type: {}", info.data_type),
57+
}
58+
59+
info_!("Additional path: {:?}", entry.path());
60+
warn_!("Keeping existing template '{}'.", name);
5061
continue;
5162
}
5263

@@ -55,7 +66,7 @@ impl Context {
5566
.unwrap_or(ContentType::Text);
5667

5768
templates.insert(name, TemplateInfo {
58-
path: Some(path.clone()),
69+
path: Some(entry.into_path()),
5970
engine_ext: ext,
6071
data_type,
6172
});

contrib/dyn_templates/src/metadata.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl<'r> FromRequest<'r> for Metadata<'r> {
153153
error_!("Uninitialized template context: missing fairing.");
154154
info_!("To use templates, you must attach `Template::fairing()`.");
155155
info_!("See the `Template` documentation for more information.");
156-
request::Outcome::Failure((Status::InternalServerError, ()))
156+
request::Outcome::Error((Status::InternalServerError, ()))
157157
})
158158
}
159159
}

contrib/dyn_templates/tests/templates.rs

+10
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,16 @@ mod tera_tests {
237237
assert_eq!(md_rendered, Some((ContentType::HTML, ESCAPED_EXPECTED.into())));
238238
}
239239

240+
#[async_test]
241+
async fn test_globby_paths() {
242+
use rocket::local::asynchronous::Client;
243+
244+
let client = Client::debug(rocket()).await.unwrap();
245+
let req = client.get("/");
246+
let metadata = Metadata::from_request(&req).await.unwrap();
247+
assert!(metadata.contains_template("tera/[test]/html_test"));
248+
}
249+
240250
// u128 is not supported. enable when it is.
241251
// #[test]
242252
// fn test_tera_u128() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{% extends "tera/base" %}
2+
{% block title %}{{ title }}{% endblock title %}
3+
{% block content %}
4+
{{ content }}
5+
{% endblock content %}

contrib/sync_db_pools/lib/src/connection.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ impl<'r, K: 'static, C: Poolable> FromRequest<'r> for Connection<K, C> {
210210
#[inline]
211211
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, ()> {
212212
match request.rocket().state::<ConnectionPool<K, C>>() {
213-
Some(c) => c.get().await.into_outcome((Status::ServiceUnavailable, ())),
213+
Some(c) => c.get().await.or_error((Status::ServiceUnavailable, ())),
214214
None => {
215215
error_!("Missing database fairing for `{}`", std::any::type_name::<K>());
216-
Outcome::Failure((Status::InternalServerError, ()))
216+
Outcome::Error((Status::InternalServerError, ()))
217217
}
218218
}
219219
}

contrib/ws/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ default = ["tungstenite"]
1717
tungstenite = ["tokio-tungstenite"]
1818

1919
[dependencies]
20-
tokio-tungstenite = { version = "0.19", optional = true }
20+
tokio-tungstenite = { version = "0.20", optional = true }
2121

2222
[dependencies.rocket]
2323
version = "=0.5.0-rc.3"

contrib/ws/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ This crate provides WebSocket support for Rocket via integration with Rocket's
2424
```rust
2525
#[get("/echo")]
2626
fn echo_stream(ws: ws::WebSocket) -> ws::Stream!['static] {
27-
ws::stream! { ws =>
27+
ws::Stream! { ws =>
2828
for await message in ws {
2929
yield message?;
3030
}

contrib/ws/src/websocket.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::result::{Result, Error};
3030
/// ### Forwarding
3131
///
3232
/// If the incoming request is not a valid WebSocket request, the guard
33-
/// forwards. The guard never fails.
33+
/// forwards with a status of `BadRequest`. The guard never fails.
3434
pub struct WebSocket {
3535
config: Config,
3636
key: String,
@@ -203,7 +203,7 @@ impl<'r> FromRequest<'r> for WebSocket {
203203
let key = headers.get_one("Sec-WebSocket-Key").map(|k| derive_accept_key(k.as_bytes()));
204204
match key {
205205
Some(key) if is_upgrade && is_ws && is_13 => Outcome::Success(WebSocket::new(key)),
206-
Some(_) | None => Outcome::Forward(Status::NotFound)
206+
Some(_) | None => Outcome::Forward(Status::BadRequest)
207207
}
208208
}
209209
}

core/codegen/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,14 @@ rust-version = "1.56"
1616
proc-macro = true
1717

1818
[dependencies]
19-
indexmap = "1.0"
19+
indexmap = "2"
2020
quote = "1.0"
2121
syn = { version = "2.0", features = ["full", "visit", "visit-mut", "extra-traits"] }
2222
proc-macro2 = "1.0.27"
2323
devise = "0.4"
2424
rocket_http = { version = "=0.5.0-rc.3", path = "../http/" }
2525
unicode-xid = "0.2"
26+
version_check = "0.9"
2627
glob = "0.3"
2728

2829
[dev-dependencies]

core/codegen/src/attribute/route/mod.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::proc_macro_ext::StringLit;
1010
use crate::syn_ext::{IdentExt, TypeExt as _};
1111
use crate::http_codegen::{Method, Optional};
1212
use crate::attribute::param::Guard;
13+
use crate::exports::mixed;
1314

1415
use self::parse::{Route, Attribute, MethodAttribute};
1516

@@ -104,7 +105,7 @@ fn query_decls(route: &Route) -> Option<TokenStream> {
104105
if !__e.is_empty() {
105106
#_log::warn_!("Query string failed to match route declaration.");
106107
for _err in __e { #_log::warn_!("{}", _err); }
107-
return #Outcome::Forward((#__data, #Status::NotFound));
108+
return #Outcome::Forward((#__data, #Status::UnprocessableEntity));
108109
}
109110

110111
(#(#ident.unwrap()),*)
@@ -125,9 +126,9 @@ fn request_guard_decl(guard: &Guard) -> TokenStream {
125126
#_log::warn_!("Request guard `{}` is forwarding.", stringify!(#ty));
126127
return #Outcome::Forward((#__data, __e));
127128
},
128-
#Outcome::Failure((__c, __e)) => {
129+
#Outcome::Error((__c, __e)) => {
129130
#_log::warn_!("Request guard `{}` failed: {:?}.", stringify!(#ty), __e);
130-
return #Outcome::Failure(__c);
131+
return #Outcome::Error(__c);
131132
}
132133
};
133134
}
@@ -145,7 +146,7 @@ fn param_guard_decl(guard: &Guard) -> TokenStream {
145146
#_log::warn_!("Parameter guard `{}: {}` is forwarding: {:?}.",
146147
#name, stringify!(#ty), __error);
147148

148-
#Outcome::Forward((#__data, #Status::NotFound))
149+
#Outcome::Forward((#__data, #Status::UnprocessableEntity))
149150
});
150151

151152
// All dynamic parameters should be found if this function is being called;
@@ -188,9 +189,9 @@ fn data_guard_decl(guard: &Guard) -> TokenStream {
188189
#_log::warn_!("Data guard `{}` is forwarding.", stringify!(#ty));
189190
return #Outcome::Forward((__d, __e));
190191
}
191-
#Outcome::Failure((__c, __e)) => {
192+
#Outcome::Error((__c, __e)) => {
192193
#_log::warn_!("Data guard `{}` failed: {:?}.", stringify!(#ty), __e);
193-
return #Outcome::Failure(__c);
194+
return #Outcome::Error(__c);
194195
}
195196
};
196197
}
@@ -224,6 +225,7 @@ fn internal_uri_macro_decl(route: &Route) -> TokenStream {
224225
}
225226

226227
#[doc(hidden)]
228+
#[allow(unused)]
227229
pub use #inner_macro_name as #macro_name;
228230
}
229231
}
@@ -242,7 +244,7 @@ fn responder_outcome_expr(route: &Route) -> TokenStream {
242244
.map(|a| quote_spanned!(a.span() => .await));
243245

244246
define_spanned_export!(ret_span => __req, _route);
245-
quote_spanned! { ret_span =>
247+
quote_spanned! { mixed(ret_span) =>
246248
let ___responder = #user_handler_fn_name(#(#parameter_names),*) #_await;
247249
#_route::Outcome::from(#__req, ___responder)
248250
}

core/codegen/src/bang/export.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,23 @@ pub fn _macro(input: proc_macro::TokenStream) -> devise::Result<TokenStream> {
3131
})
3232
.collect();
3333

34+
// Only try using the `macro` syntax on nightly/dev or when we don't know.
35+
let export = match version_check::is_feature_flaggable() {
36+
Some(true) | None => quote! {
37+
#(#attrs)*
38+
#[cfg(all(nightly, doc))]
39+
pub macro #macro_name {
40+
#decl_macro_tokens
41+
}
42+
43+
#[cfg(not(all(nightly, doc)))]
44+
pub use #mod_name::#internal_name as #macro_name;
45+
},
46+
Some(false) => quote! {
47+
pub use #mod_name::#internal_name as #macro_name;
48+
}
49+
};
50+
3451
Ok(quote! {
3552
#[allow(non_snake_case)]
3653
mod #mod_name {
@@ -43,13 +60,6 @@ pub fn _macro(input: proc_macro::TokenStream) -> devise::Result<TokenStream> {
4360
pub use #internal_name;
4461
}
4562

46-
#(#attrs)*
47-
#[cfg(all(nightly, doc))]
48-
pub macro #macro_name {
49-
#decl_macro_tokens
50-
}
51-
52-
#[cfg(not(all(nightly, doc)))]
53-
pub use #mod_name::#internal_name as #macro_name;
63+
#export
5464
})
5565
}

core/codegen/src/bang/uri.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ fn add_binding<P: fmt::Part>(to: &mut Vec<TokenStream>, ident: &Ident, ty: &Type
126126
let tmp_ident = ident.clone().with_span(expr.span());
127127
let let_stmt = quote_spanned!(span => let #tmp_ident = #expr);
128128

129-
to.push(quote_spanned!(span =>
129+
to.push(quote_spanned!(mixed(span) =>
130130
#[allow(non_snake_case)] #let_stmt;
131131
let #ident = <#ty as #_fmt::FromUriParam<#part, _>>::from_uri_param(#tmp_ident);
132132
));

core/codegen/src/bang/uri_parsing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ impl Arg {
430430
fn unnamed(&self) -> &ArgExpr {
431431
match self {
432432
Arg::Unnamed(expr) => expr,
433-
_ => panic!("Called Arg::unnamed() on an Arg::named!"),
433+
_ => panic!("Called Arg::unnamed() on an Arg::Named!"),
434434
}
435435
}
436436

core/codegen/src/derive/from_form.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ pub fn derive_from_form(input: proc_macro::TokenStream) -> TokenStream {
123123
Ok(quote_spanned! { input.span() =>
124124
/// Rocket generated FormForm context.
125125
#[doc(hidden)]
126-
#[allow(private_in_public)]
126+
#[allow(unknown_lints)]
127+
#[allow(renamed_and_removed_lints)]
128+
#[allow(private_in_public, private_bounds)]
127129
#vis struct #ctxt_ty #impl_gen #where_clause {
128130
__opts: #_form::Options,
129131
__errors: #_form::Errors<'r>,
@@ -148,6 +150,7 @@ pub fn derive_from_form(input: proc_macro::TokenStream) -> TokenStream {
148150
#[allow(unused_imports)]
149151
use #_http::uncased::AsUncased;
150152
})
153+
.outer_mapper(quote!(#[allow(renamed_and_removed_lints)]))
151154
.outer_mapper(quote!(#[allow(private_in_public)]))
152155
.outer_mapper(quote!(#[rocket::async_trait]))
153156
.inner_mapper(MapperBuild::new()

core/codegen/src/exports.rs

+6
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,9 @@ define_exported_paths! {
106106
macro_rules! define_spanned_export {
107107
($span:expr => $($name:ident),*) => ($(define!($span => $name $name);)*)
108108
}
109+
110+
/// Convenience: returns a "mixed site" span located at `span`.
111+
#[inline(always)]
112+
pub fn mixed(span: Span) -> Span {
113+
Span::mixed_site().located_at(span)
114+
}

core/codegen/src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,7 @@ macro_rules! route_attribute {
239239
///
240240
/// If a request guard fails, the request is forwarded if the
241241
/// [`Outcome`] is `Forward` or failed if the [`Outcome`] is
242-
/// `Failure`. See [`FromRequest` Outcomes] for further
243-
/// detail.
242+
/// `Error`. See [`FromRequest` Outcomes] for further detail.
244243
///
245244
/// 2. Path and query guards in an unspecified order. If a path
246245
/// or query guard fails, the request is forwarded.
@@ -249,7 +248,7 @@ macro_rules! route_attribute {
249248
///
250249
/// If a data guard fails, the request is forwarded if the
251250
/// [`Outcome`] is `Forward` or failed if the [`Outcome`] is
252-
/// `Failure`. See [`FromData`] for further detail.
251+
/// `Error`. See [`FromData`] for further detail.
253252
///
254253
/// If all validation succeeds, the decorated function is called.
255254
/// The returned value is used to generate a [`Response`] via the
@@ -448,7 +447,7 @@ pub fn main(args: TokenStream, input: TokenStream) -> TokenStream {
448447
/// #[rocket::main]
449448
/// async fn main() {
450449
/// // Recall that an uninspected `Error` will cause a pretty-printed panic,
451-
/// // so rest assured failures do not go undetected when using `#[launch]`.
450+
/// // so rest assured errors do not go undetected when using `#[launch]`.
452451
/// let _ = rocket().launch().await;
453452
/// }
454453
/// ```
@@ -1457,6 +1456,7 @@ pub fn catchers(input: TokenStream) -> TokenStream {
14571456
/// are not ignorable.
14581457
///
14591458
/// [`Uri`]: ../rocket/http/uri/enum.Uri.html
1459+
/// [`Uri::parse_any()`]: ../rocket/http/uri/enum.Uri.html#method.parse_any
14601460
/// [`Origin`]: ../rocket/http/uri/struct.Origin.html
14611461
/// [`Asterisk`]: ../rocket/http/uri/struct.Asterisk.html
14621462
/// [`Authority`]: ../rocket/http/uri/struct.Authority.html

core/codegen/tests/from_form.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ fn json_wrapper_works() {
984984
assert_eq!(form, JsonToken(Json("foo bar")));
985985
}
986986

987-
// FIXME: https://github.com/rust-lang/rust/issues/86706
987+
#[allow(renamed_and_removed_lints)]
988988
#[allow(private_in_public)]
989989
struct Q<T>(T);
990990

0 commit comments

Comments
 (0)