mirror of https://github.com/rwf2/Rocket.git
Allow custom generic bounds in 'Responder' derive.
This commit is contained in:
parent
02d6c4c6f1
commit
41d7138540
|
@ -14,7 +14,7 @@ proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "df00b5" }
|
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "f2431b" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
version_check = "0.9"
|
version_check = "0.9"
|
||||||
|
|
|
@ -19,12 +19,12 @@ indexmap = "1.0"
|
||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "1.0.72", features = ["full", "visit", "visit-mut", "extra-traits"] }
|
syn = { version = "1.0.72", features = ["full", "visit", "visit-mut", "extra-traits"] }
|
||||||
proc-macro2 = "1.0.27"
|
proc-macro2 = "1.0.27"
|
||||||
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "df00b5" }
|
devise = { git = "https://github.com/SergioBenitez/Devise.git", rev = "f2431b" }
|
||||||
rocket_http = { version = "0.5.0-dev", path = "../http/" }
|
rocket_http = { version = "0.5.0-dev", path = "../http/" }
|
||||||
unicode-xid = "0.2"
|
unicode-xid = "0.2"
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rocket = { version = "0.5.0-dev", path = "../lib" }
|
rocket = { version = "0.5.0-dev", path = "../lib", features = ["json"] }
|
||||||
version_check = "0.9"
|
version_check = "0.9"
|
||||||
trybuild = "1.0"
|
trybuild = "1.0"
|
||||||
|
|
|
@ -47,8 +47,8 @@ fn context_type(input: Input<'_>) -> (TokenStream, Option<syn::WhereClause>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let span = input.ident().span();
|
let span = input.ident().span();
|
||||||
gen.add_type_bound(&syn::parse_quote!(#_form::FromForm<#lifetime>));
|
gen.add_type_bound(syn::parse_quote!(#_form::FromForm<#lifetime>));
|
||||||
gen.add_type_bound(&syn::TypeParamBound::from(lifetime));
|
gen.add_type_bound(syn::TypeParamBound::from(lifetime));
|
||||||
let (_, ty_gen, where_clause) = gen.split_for_impl();
|
let (_, ty_gen, where_clause) = gen.split_for_impl();
|
||||||
(quote_spanned!(span => FromFormGeneratedContext #ty_gen), where_clause.cloned())
|
(quote_spanned!(span => FromFormGeneratedContext #ty_gen), where_clause.cloned())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use devise::{*, ext::{TypeExt, SpanDiagnosticExt}};
|
use devise::{*, ext::{TypeExt, SpanDiagnosticExt, GenericsExt}};
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
|
use syn::punctuated::Punctuated;
|
||||||
|
use syn::parse::Parser;
|
||||||
|
|
||||||
use crate::exports::*;
|
use crate::exports::*;
|
||||||
use crate::http_codegen::{ContentType, Status};
|
use crate::http_codegen::{ContentType, Status};
|
||||||
|
|
||||||
|
type WherePredicates = Punctuated<syn::WherePredicate, syn::Token![,]>;
|
||||||
|
|
||||||
#[derive(Debug, Default, FromMeta)]
|
#[derive(Debug, Default, FromMeta)]
|
||||||
struct ItemAttr {
|
struct ItemAttr {
|
||||||
|
bound: Option<SpanWrapped<String>>,
|
||||||
content_type: Option<SpanWrapped<ContentType>>,
|
content_type: Option<SpanWrapped<ContentType>>,
|
||||||
status: Option<SpanWrapped<Status>>,
|
status: Option<SpanWrapped<Status>>,
|
||||||
}
|
}
|
||||||
|
@ -17,20 +22,32 @@ struct FieldAttr {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn derive_responder(input: proc_macro::TokenStream) -> TokenStream {
|
pub fn derive_responder(input: proc_macro::TokenStream) -> TokenStream {
|
||||||
let impl_tokens = quote!(impl<'__r, '__o: '__r> ::rocket::response::Responder<'__r, '__o>);
|
let impl_tokens = quote!(impl<'r, 'o: 'r> ::rocket::response::Responder<'r, 'o>);
|
||||||
DeriveGenerator::build_for(input, impl_tokens)
|
DeriveGenerator::build_for(input, impl_tokens)
|
||||||
.support(Support::Struct | Support::Enum | Support::Lifetime | Support::Type)
|
.support(Support::Struct | Support::Enum | Support::Lifetime | Support::Type)
|
||||||
.replace_generic(1, 0)
|
.replace_generic(1, 0)
|
||||||
.type_bound(quote!(::rocket::response::Responder<'__r, '__o>))
|
.type_bound_mapper(MapperBuild::new()
|
||||||
|
.try_input_map(|_, input| {
|
||||||
|
ItemAttr::one_from_attrs("response", input.attrs())?
|
||||||
|
.and_then(|attr| attr.bound)
|
||||||
|
.map(|bound| {
|
||||||
|
let span = bound.span;
|
||||||
|
let bounds = WherePredicates::parse_terminated.parse_str(&bound)
|
||||||
|
.map_err(|e| span.error(format!("invalid bound syntax: {}", e)))?;
|
||||||
|
Ok(quote_respanned!(span => #bounds))
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let bound = quote!(::rocket::response::Responder<'r, 'o>);
|
||||||
|
let preds = input.generics().parsed_bounded_types(bound)?;
|
||||||
|
Ok(quote!(#preds))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
.validator(ValidatorBuild::new()
|
.validator(ValidatorBuild::new()
|
||||||
.input_validate(|_, i| match i.generics().lifetimes().count() > 1 {
|
.input_validate(|_, i| match i.generics().lifetimes().count() > 1 {
|
||||||
true => Err(i.generics().span().error("only one lifetime is supported")),
|
true => Err(i.generics().span().error("only one lifetime is supported")),
|
||||||
false => Ok(())
|
false => Ok(())
|
||||||
})
|
})
|
||||||
.input_validate(|_, i| match i.generics().type_params().count() > 1 {
|
|
||||||
true => Err(i.generics().span().error("only one type generic is supported")),
|
|
||||||
false => Ok(())
|
|
||||||
})
|
|
||||||
.fields_validate(|_, fields| match fields.is_empty() {
|
.fields_validate(|_, fields| match fields.is_empty() {
|
||||||
true => return Err(fields.span().error("need at least one field")),
|
true => return Err(fields.span().error("need at least one field")),
|
||||||
false => Ok(())
|
false => Ok(())
|
||||||
|
@ -38,7 +55,7 @@ pub fn derive_responder(input: proc_macro::TokenStream) -> TokenStream {
|
||||||
)
|
)
|
||||||
.inner_mapper(MapperBuild::new()
|
.inner_mapper(MapperBuild::new()
|
||||||
.with_output(|_, output| quote! {
|
.with_output(|_, output| quote! {
|
||||||
fn respond_to(self, __req: &'__r #Request<'_>) -> #_response::Result<'__o> {
|
fn respond_to(self, __req: &'r #Request<'_>) -> #_response::Result<'o> {
|
||||||
#output
|
#output
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -758,29 +758,52 @@ pub fn derive_from_form(input: TokenStream) -> TokenStream {
|
||||||
///
|
///
|
||||||
/// # Generics
|
/// # Generics
|
||||||
///
|
///
|
||||||
/// The derive accepts at most one type generic and at most one lifetime
|
/// The derive accepts any number of type generics and at most one lifetime
|
||||||
/// generic. If a type generic is present, the generated implementation will
|
/// generic. If a type generic is present, the generated implementation will
|
||||||
/// require a bound of `Responder` for the generic. As such, the generic should
|
/// require a bound of `Responder<'r, 'o>` for each generic unless a
|
||||||
/// be used as a `Responder`:
|
/// `#[response(bound = ...)]` attribute as used:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #[macro_use] extern crate rocket;
|
/// # #[macro_use] extern crate rocket;
|
||||||
|
/// use rocket::serde::Serialize;
|
||||||
|
/// use rocket::serde::json::Json;
|
||||||
|
/// use rocket::http::ContentType;
|
||||||
|
/// use rocket::response::Responder;
|
||||||
|
///
|
||||||
|
/// // The bound `T: Responder` will be added to the generated implementation.
|
||||||
/// #[derive(Responder)]
|
/// #[derive(Responder)]
|
||||||
/// #[response(status = 404, content_type = "html")]
|
/// #[response(status = 404, content_type = "html")]
|
||||||
/// struct NotFoundHtml<T>(T);
|
/// struct NotFoundHtml<T>(T);
|
||||||
|
///
|
||||||
|
/// // The bound `T: Serialize` will be added to the generated implementation.
|
||||||
|
/// // This would fail to compile otherwise.
|
||||||
|
/// #[derive(Responder)]
|
||||||
|
/// #[response(bound = "T: Serialize", status = 404)]
|
||||||
|
/// struct NotFoundJson<T>(Json<T>);
|
||||||
|
///
|
||||||
|
/// // The bounds `T: Serialize, E: Responder` will be added to the generated
|
||||||
|
/// // implementation. This would fail to compile otherwise.
|
||||||
|
/// #[derive(Responder)]
|
||||||
|
/// #[response(bound = "T: Serialize, E: Responder<'r, 'o>")]
|
||||||
|
/// enum MyResult<T, E> {
|
||||||
|
/// Ok(Json<T>),
|
||||||
|
/// #[response(status = 404)]
|
||||||
|
/// Err(E, ContentType)
|
||||||
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// If a lifetime generic is present, it will be used as the second lifetime
|
/// If a lifetime generic is present, it will be replace with `'o` in the
|
||||||
/// paramter `'o` parameter in `impl Responder<'r, 'o>`:
|
/// generated implementation `impl Responder<'r, 'o>`:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #[macro_use] extern crate rocket;
|
/// # #[macro_use] extern crate rocket;
|
||||||
|
/// // Generates `impl<'r, 'o> Responder<'r, 'o> for NotFoundHtmlString<'o>`.
|
||||||
/// #[derive(Responder)]
|
/// #[derive(Responder)]
|
||||||
/// #[response(status = 404, content_type = "html")]
|
/// #[response(status = 404, content_type = "html")]
|
||||||
/// struct NotFoundHtmlString<'o>(&'o str);
|
/// struct NotFoundHtmlString<'a>(&'a str);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Both a type generic and lifetime generic may be used:
|
/// Both type generics and lifetime generic may be used:
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # #[macro_use] extern crate rocket;
|
/// # #[macro_use] extern crate rocket;
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Rocket sometimes generates mangled identifiers that activate the
|
||||||
|
// non_snake_case lint. We deny the lint in this test to ensure that
|
||||||
|
// code generation uses #[allow(non_snake_case)] in the appropriate places.
|
||||||
|
#![deny(non_snake_case)]
|
||||||
|
|
||||||
|
#[macro_use] extern crate rocket;
|
||||||
|
|
||||||
|
use rocket::{Request, Rocket, Build};
|
||||||
|
use rocket::local::blocking::Client;
|
||||||
|
use rocket::http::{Status, ContentType};
|
||||||
|
|
||||||
|
#[catch(404)] fn not_found_0() -> &'static str { "404-0" }
|
||||||
|
#[catch(404)] fn not_found_1(_: &Request) -> &'static str { "404-1" }
|
||||||
|
#[catch(404)] fn not_found_2(_: Status, _: &Request) -> &'static str { "404-2" }
|
||||||
|
#[catch(default)] fn all(_: Status, r: &Request) -> String { r.uri().to_string() }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple_catchers() {
|
||||||
|
fn rocket() -> Rocket<Build> {
|
||||||
|
rocket::build()
|
||||||
|
.register("/0", catchers![not_found_0])
|
||||||
|
.register("/1", catchers![not_found_1])
|
||||||
|
.register("/2", catchers![not_found_2])
|
||||||
|
.register("/", catchers![all])
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = Client::debug(rocket()).unwrap();
|
||||||
|
for i in 0..6 {
|
||||||
|
let response = client.get(format!("/{}", i)).dispatch();
|
||||||
|
assert_eq!(response.status(), Status::NotFound);
|
||||||
|
|
||||||
|
match i {
|
||||||
|
0..=2 => assert_eq!(response.into_string().unwrap(), format!("404-{}", i)),
|
||||||
|
_ => assert_eq!(response.into_string().unwrap(), format!("/{}", i)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/<code>")] fn forward(code: u16) -> Status { Status::new(code) }
|
||||||
|
#[catch(400)] fn forward_400(status: Status, _: &Request) -> String { status.code.to_string() }
|
||||||
|
#[catch(404)] fn forward_404(status: Status, _: &Request) -> String { status.code.to_string() }
|
||||||
|
#[catch(444)] fn forward_444(status: Status, _: &Request) -> String { status.code.to_string() }
|
||||||
|
#[catch(500)] fn forward_500(status: Status, _: &Request) -> String { status.code.to_string() }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_status_param() {
|
||||||
|
fn rocket() -> Rocket<Build> {
|
||||||
|
rocket::build()
|
||||||
|
.mount("/", routes![forward])
|
||||||
|
.register("/", catchers![forward_400, forward_404, forward_444, forward_500])
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = Client::debug(rocket()).unwrap();
|
||||||
|
for code in &[400, 404, 444, 400, 800, 3480] {
|
||||||
|
let response = client.get(uri!(forward(*code))).dispatch();
|
||||||
|
let code = std::cmp::min(*code, 500);
|
||||||
|
assert_eq!(response.status(), Status::new(code));
|
||||||
|
assert_eq!(response.into_string().unwrap(), code.to_string());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use rocket::local::asynchronous::Client;
|
use rocket::local::asynchronous::Client;
|
||||||
use rocket::response::Responder;
|
|
||||||
use rocket::http::{Status, ContentType, Cookie};
|
use rocket::http::{Status, ContentType, Cookie};
|
||||||
|
use rocket::response::Responder;
|
||||||
|
|
||||||
#[derive(Responder)]
|
#[derive(Responder)]
|
||||||
pub enum Foo<'r> {
|
pub enum Foo<'r> {
|
||||||
|
@ -107,3 +107,42 @@ async fn responder_baz() {
|
||||||
assert_eq!(r.content_type(), Some(ContentType::new("application", "x-custom")));
|
assert_eq!(r.content_type(), Some(ContentType::new("application", "x-custom")));
|
||||||
assert_eq!(r.body_mut().to_string().await.unwrap(), "just a custom");
|
assert_eq!(r.body_mut().to_string().await.unwrap(), "just a custom");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
|
||||||
|
// The bounds `T: Serialize, E: Responder` will be added to the generated
|
||||||
|
// implementation. This would fail to compile otherwise.
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(bound = "T: rocket::serde::Serialize, E: Responder<'r, 'o>")]
|
||||||
|
enum MyResult<'a, T, E> {
|
||||||
|
Ok(Json<T>),
|
||||||
|
#[response(status = 404)]
|
||||||
|
Err(E, ContentType),
|
||||||
|
#[response(status = 500)]
|
||||||
|
Other(&'a str),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rocket::async_test]
|
||||||
|
async fn generic_responder() {
|
||||||
|
let client = Client::debug_with(vec![]).await.expect("valid rocket");
|
||||||
|
let local_req = client.get("/");
|
||||||
|
let req = local_req.inner();
|
||||||
|
|
||||||
|
let v: MyResult<_, ()> = MyResult::Ok(Json("hi"));
|
||||||
|
let mut r = v.respond_to(req).unwrap();
|
||||||
|
assert_eq!(r.status(), Status::Ok);
|
||||||
|
assert_eq!(r.content_type().unwrap(), ContentType::JSON);
|
||||||
|
assert_eq!(r.body_mut().to_string().await.unwrap(), "\"hi\"");
|
||||||
|
|
||||||
|
let v: MyResult<(), &[u8]> = MyResult::Err(&[7, 13, 23], ContentType::JPEG);
|
||||||
|
let mut r = v.respond_to(req).unwrap();
|
||||||
|
assert_eq!(r.status(), Status::NotFound);
|
||||||
|
assert_eq!(r.content_type().unwrap(), ContentType::JPEG);
|
||||||
|
assert_eq!(r.body_mut().to_bytes().await.unwrap(), vec![7, 13, 23]);
|
||||||
|
|
||||||
|
let v: MyResult<(), &[u8]> = MyResult::Other("beep beep");
|
||||||
|
let mut r = v.respond_to(req).unwrap();
|
||||||
|
assert_eq!(r.status(), Status::InternalServerError);
|
||||||
|
assert_eq!(r.content_type().unwrap(), ContentType::Text);
|
||||||
|
assert_eq!(r.body_mut().to_string().await.unwrap(), "beep beep");
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../ui-fail/responder.rs
|
|
@ -1,158 +1,217 @@
|
||||||
error: need at least one field
|
error: need at least one field
|
||||||
--> $DIR/responder.rs:6:1
|
--> $DIR/responder.rs:4:1
|
||||||
|
|
|
|
||||||
6 | struct Thing1;
|
4 | struct Thing1;
|
||||||
| ^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:5:10
|
--> $DIR/responder.rs:3:10
|
||||||
|
|
|
|
||||||
5 | #[derive(Responder)]
|
3 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: need at least one field
|
error: need at least one field
|
||||||
--> $DIR/responder.rs:10:14
|
--> $DIR/responder.rs:7:14
|
||||||
|
|
|
|
||||||
10 | struct Thing2();
|
7 | struct Thing2();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:9:10
|
--> $DIR/responder.rs:6:10
|
||||||
|
|
|
|
||||||
9 | #[derive(Responder)]
|
6 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: need at least one field
|
error: need at least one field
|
||||||
--> $DIR/responder.rs:15:5
|
--> $DIR/responder.rs:13:12
|
||||||
|
|
|
|
||||||
15 | Bark,
|
13 | enum Foo { Bark, }
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:13:10
|
--> $DIR/responder.rs:12:10
|
||||||
|
|
|
|
||||||
13 | #[derive(Responder)]
|
12 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: only one lifetime is supported
|
error: only one lifetime is supported
|
||||||
--> $DIR/responder.rs:20:14
|
--> $DIR/responder.rs:16:14
|
||||||
|
|
|
|
||||||
20 | struct Thing4<'a, 'b>(&'a str, &'b str);
|
16 | struct Thing4<'a, 'b>(&'a str, &'b str);
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:19:10
|
--> $DIR/responder.rs:15:10
|
||||||
|
|
|
|
||||||
19 | #[derive(Responder)]
|
15 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type generics are not supported
|
error: invalid or unknown content type
|
||||||
--> $DIR/responder.rs:24:15
|
--> $DIR/responder.rs:25:27
|
||||||
|
|
|
|
||||||
24 | struct Thing5<T>(T);
|
25 | #[response(content_type = "")]
|
||||||
| ^
|
| ^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:23:10
|
--> $DIR/responder.rs:24:10
|
||||||
|
|
|
|
||||||
23 | #[derive(Responder)]
|
24 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: type generics are not supported
|
error: invalid or unknown content type
|
||||||
--> $DIR/responder.rs:28:23
|
--> $DIR/responder.rs:29:27
|
||||||
|
|
|
|
||||||
28 | struct Thing6<'a, 'b, T>(&'a str, &'b str, T);
|
29 | #[response(content_type = "idk")]
|
||||||
| ^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:27:10
|
--> $DIR/responder.rs:28:10
|
||||||
|
|
|
|
||||||
27 | #[derive(Responder)]
|
28 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: invalid or unknown content-type
|
error: invalid value: expected string literal
|
||||||
--> $DIR/responder.rs:33:31
|
--> $DIR/responder.rs:33:27
|
||||||
|
|
|
|
||||||
33 | #[response(content_type = "")]
|
33 | #[response(content_type = 100)]
|
||||||
| ^^
|
| ^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:31:10
|
--> $DIR/responder.rs:32:10
|
||||||
|
|
|
|
||||||
31 | #[derive(Responder)]
|
32 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: invalid or unknown content-type
|
error: status must be in range [100, 599]
|
||||||
--> $DIR/responder.rs:40:31
|
--> $DIR/responder.rs:37:21
|
||||||
|
|
|
|
||||||
40 | #[response(content_type = "idk")]
|
37 | #[response(status = 8)]
|
||||||
| ^^^^^
|
| ^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:38:10
|
--> $DIR/responder.rs:36:10
|
||||||
|
|
|
|
||||||
38 | #[derive(Responder)]
|
36 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: invalid value: expected string
|
error: invalid value: expected unsigned integer literal
|
||||||
--> $DIR/responder.rs:47:31
|
--> $DIR/responder.rs:41:21
|
||||||
|
|
|
|
||||||
47 | #[response(content_type = 100)]
|
41 | #[response(status = "404")]
|
||||||
| ^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:45:10
|
--> $DIR/responder.rs:40:10
|
||||||
|
|
|
|
||||||
45 | #[derive(Responder)]
|
40 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: status must be in range [100, 600)
|
error: invalid value: expected unsigned integer literal
|
||||||
--> $DIR/responder.rs:54:25
|
--> $DIR/responder.rs:45:21
|
||||||
|
|
|
|
||||||
54 | #[response(status = 8)]
|
45 | #[response(status = "404", content_type = "html")]
|
||||||
| ^
|
| ^^^^^
|
||||||
|
|
|
||||||
|
note: error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:44:10
|
||||||
|
|
|
||||||
|
44 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected string literal
|
||||||
|
--> $DIR/responder.rs:49:41
|
||||||
|
|
|
||||||
|
49 | #[response(status = 404, content_type = 120)]
|
||||||
|
| ^^^
|
||||||
|
|
|
||||||
|
note: error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:48:10
|
||||||
|
|
|
||||||
|
48 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected string literal
|
||||||
|
--> $DIR/responder.rs:53:20
|
||||||
|
|
|
||||||
|
53 | #[response(bound = 10)]
|
||||||
|
| ^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:52:10
|
--> $DIR/responder.rs:52:10
|
||||||
|
|
|
|
||||||
52 | #[derive(Responder)]
|
52 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: invalid value: expected unsigned integer
|
error: invalid bound syntax: expected `:`
|
||||||
--> $DIR/responder.rs:61:25
|
--> $DIR/responder.rs:65:20
|
||||||
|
|
|
|
||||||
61 | #[response(status = "404")]
|
65 | #[response(bound = "ponies are cool")]
|
||||||
| ^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:59:10
|
--> $DIR/responder.rs:64:10
|
||||||
|
|
|
|
||||||
59 | #[derive(Responder)]
|
64 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: invalid value: expected unsigned integer
|
error: invalid bound syntax: expected `,`
|
||||||
--> $DIR/responder.rs:68:25
|
--> $DIR/responder.rs:69:20
|
||||||
|
|
|
|
||||||
68 | #[response(status = "404", content_type = "html")]
|
69 | #[response(bound = "T: ROCKETS + ARE COOLER")]
|
||||||
| ^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
note: error occurred while deriving `Responder`
|
||||||
--> $DIR/responder.rs:66:10
|
--> $DIR/responder.rs:68:10
|
||||||
|
|
|
|
||||||
66 | #[derive(Responder)]
|
68 | #[derive(Responder)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
= note: this error originates in the derive macro `Responder` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: invalid value: expected string
|
error[E0277]: the trait bound `Header<'_>: From<E>` is not satisfied
|
||||||
--> $DIR/responder.rs:75:45
|
--> $DIR/responder.rs:22:24
|
||||||
|
|
|
|
||||||
75 | #[response(status = 404, content_type = 120)]
|
22 | struct Thing6<T, E>(T, E); // NO ERROR
|
||||||
| ^^^
|
| ^ the trait `From<E>` is not implemented for `Header<'_>`
|
||||||
|
|
|
|
||||||
note: error occurred while deriving `Responder`
|
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `E`
|
||||||
--> $DIR/responder.rs:73:10
|
help: consider extending the `where` bound, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
|
||||||
73 | #[derive(Responder)]
|
21 | #[derive(Responder, Header<'_>: From<E>)]
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 13 previous errors
|
error[E0277]: the trait bound `T: Responder<'_, '_>` is not satisfied
|
||||||
|
--> $DIR/responder.rs:58:19
|
||||||
|
|
|
||||||
|
58 | struct Thing15<T>(T);
|
||||||
|
| ^ the trait `Responder<'_, '_>` is not implemented for `T`
|
||||||
|
|
|
||||||
|
= note: required by `respond_to`
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
57 | #[response(bound = "T: std::fmt::Display" + rocket::response::Responder<'_, '_>)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Responder<'_, '_>` is not satisfied
|
||||||
|
--> $DIR/responder.rs:62:19
|
||||||
|
|
|
||||||
|
62 | struct Thing16<T>(T);
|
||||||
|
| ^ the trait `Responder<'_, '_>` is not implemented for `T`
|
||||||
|
|
|
||||||
|
= note: required by `respond_to`
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
61 | #[response(bound = "T: std::fmt::Display" + rocket::response::Responder<'_, '_>)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
../ui-fail/responder.rs
|
|
@ -0,0 +1,231 @@
|
||||||
|
error: need at least one field
|
||||||
|
--> $DIR/responder.rs:4:1
|
||||||
|
|
|
||||||
|
4 | struct Thing1;
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:3:10
|
||||||
|
|
|
||||||
|
3 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: need at least one field
|
||||||
|
--> $DIR/responder.rs:7:14
|
||||||
|
|
|
||||||
|
7 | struct Thing2();
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:6:10
|
||||||
|
|
|
||||||
|
6 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: need at least one field
|
||||||
|
--> $DIR/responder.rs:13:12
|
||||||
|
|
|
||||||
|
13 | enum Foo { Bark, }
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:12:10
|
||||||
|
|
|
||||||
|
12 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: only one lifetime is supported
|
||||||
|
--> $DIR/responder.rs:16:14
|
||||||
|
|
|
||||||
|
16 | struct Thing4<'a, 'b>(&'a str, &'b str);
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:15:10
|
||||||
|
|
|
||||||
|
15 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid or unknown content type
|
||||||
|
--> $DIR/responder.rs:25:27
|
||||||
|
|
|
||||||
|
25 | #[response(content_type = "")]
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:24:10
|
||||||
|
|
|
||||||
|
24 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid or unknown content type
|
||||||
|
--> $DIR/responder.rs:29:27
|
||||||
|
|
|
||||||
|
29 | #[response(content_type = "idk")]
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:28:10
|
||||||
|
|
|
||||||
|
28 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected string literal
|
||||||
|
--> $DIR/responder.rs:33:27
|
||||||
|
|
|
||||||
|
33 | #[response(content_type = 100)]
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:32:10
|
||||||
|
|
|
||||||
|
32 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: status must be in range [100, 599]
|
||||||
|
--> $DIR/responder.rs:37:21
|
||||||
|
|
|
||||||
|
37 | #[response(status = 8)]
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:36:10
|
||||||
|
|
|
||||||
|
36 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected unsigned integer literal
|
||||||
|
--> $DIR/responder.rs:41:21
|
||||||
|
|
|
||||||
|
41 | #[response(status = "404")]
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:40:10
|
||||||
|
|
|
||||||
|
40 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected unsigned integer literal
|
||||||
|
--> $DIR/responder.rs:45:21
|
||||||
|
|
|
||||||
|
45 | #[response(status = "404", content_type = "html")]
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:44:10
|
||||||
|
|
|
||||||
|
44 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected string literal
|
||||||
|
--> $DIR/responder.rs:49:41
|
||||||
|
|
|
||||||
|
49 | #[response(status = 404, content_type = 120)]
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:48:10
|
||||||
|
|
|
||||||
|
48 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid value: expected string literal
|
||||||
|
--> $DIR/responder.rs:53:20
|
||||||
|
|
|
||||||
|
53 | #[response(bound = 10)]
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:52:10
|
||||||
|
|
|
||||||
|
52 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid bound syntax: expected `:`
|
||||||
|
--> $DIR/responder.rs:65:20
|
||||||
|
|
|
||||||
|
65 | #[response(bound = "ponies are cool")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:64:10
|
||||||
|
|
|
||||||
|
64 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: invalid bound syntax: expected `,`
|
||||||
|
--> $DIR/responder.rs:69:20
|
||||||
|
|
|
||||||
|
69 | #[response(bound = "T: ROCKETS + ARE COOLER")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: [note] error occurred while deriving `Responder`
|
||||||
|
--> $DIR/responder.rs:68:10
|
||||||
|
|
|
||||||
|
68 | #[derive(Responder)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `Header<'_>: From<E>` is not satisfied
|
||||||
|
--> $DIR/responder.rs:22:24
|
||||||
|
|
|
||||||
|
22 | struct Thing6<T, E>(T, E); // NO ERROR
|
||||||
|
| ^ the trait `From<E>` is not implemented for `Header<'_>`
|
||||||
|
|
|
||||||
|
= note: required because of the requirements on the impl of `Into<Header<'_>>` for `E`
|
||||||
|
help: consider extending the `where` bound, but there might be an alternative better way to express this requirement
|
||||||
|
|
|
||||||
|
21 | #[derive(Responder, Header<'_>: From<E>)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Responder<'_, '_>` is not satisfied
|
||||||
|
--> $DIR/responder.rs:58:19
|
||||||
|
|
|
||||||
|
58 | struct Thing15<T>(T);
|
||||||
|
| ^ the trait `Responder<'_, '_>` is not implemented for `T`
|
||||||
|
|
|
||||||
|
= note: required by `respond_to`
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
57 | #[response(bound = "T: std::fmt::Display" + Responder<'_, '_>)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: Responder<'_, '_>` is not satisfied
|
||||||
|
--> $DIR/responder.rs:62:19
|
||||||
|
|
|
||||||
|
62 | struct Thing16<T>(T);
|
||||||
|
| ^ the trait `Responder<'_, '_>` is not implemented for `T`
|
||||||
|
|
|
||||||
|
= note: required by `respond_to`
|
||||||
|
help: consider further restricting this bound
|
||||||
|
|
|
||||||
|
61 | #[response(bound = "T: std::fmt::Display" + Responder<'_, '_>)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
|
@ -0,0 +1,72 @@
|
||||||
|
#[macro_use] extern crate rocket;
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
struct Thing1;
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
struct Thing2();
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
enum Bar { } // NO ERROR
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
enum Foo { Bark, }
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
struct Thing4<'a, 'b>(&'a str, &'b str);
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
struct Thing5<T>(T); // NO ERROR
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
struct Thing6<T, E>(T, E); // NO ERROR
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(content_type = "")]
|
||||||
|
struct Thing7(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(content_type = "idk")]
|
||||||
|
struct Thing8(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(content_type = 100)]
|
||||||
|
struct Thing9(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(status = 8)]
|
||||||
|
struct Thing10(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(status = "404")]
|
||||||
|
struct Thing11(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(status = "404", content_type = "html")]
|
||||||
|
struct Thing12(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(status = 404, content_type = 120)]
|
||||||
|
struct Thing13(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(bound = 10)]
|
||||||
|
struct Thing14(());
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(bound = "T: std::fmt::Display")]
|
||||||
|
struct Thing15<T>(T);
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(bound = "T: std::fmt::Display")]
|
||||||
|
struct Thing16<T>(T);
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(bound = "ponies are cool")]
|
||||||
|
struct Thing17<T>(T);
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(bound = "T: ROCKETS + ARE COOLER")]
|
||||||
|
struct Thing18<T>(T);
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Symlinks all of the tests in this directory with those in sibling
|
||||||
|
# `ui-fail-stable` and `ui-fail-nightly` directories.
|
||||||
|
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
|
||||||
|
stable="${SCRIPT_DIR}/../ui-fail-stable"
|
||||||
|
nightly="${SCRIPT_DIR}/../ui-fail-nightly"
|
||||||
|
anchor="$(basename ${SCRIPT_DIR})"
|
||||||
|
|
||||||
|
echo ":: Synchronizing..."
|
||||||
|
echo " stable: ${stable}"
|
||||||
|
echo " nightly: ${nightly}"
|
||||||
|
echo " anchor: ${anchor}"
|
||||||
|
|
||||||
|
for dir in "${stable}" "${nightly}"; do
|
||||||
|
find "${dir}" -type l -delete
|
||||||
|
|
||||||
|
for file in "${SCRIPT_DIR}"/*.rs; do
|
||||||
|
ln -s "../${anchor}/$(basename $file)" "${dir}/"
|
||||||
|
done
|
||||||
|
done
|
|
@ -160,6 +160,7 @@ impl<'r, T: Deserialize<'r>> MsgPack<T> {
|
||||||
Self::from_bytes(local_cache!(req, bytes))
|
Self::from_bytes(local_cache!(req, bytes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[crate::async_trait]
|
#[crate::async_trait]
|
||||||
impl<'r, T: Deserialize<'r>> FromData<'r> for MsgPack<T> {
|
impl<'r, T: Deserialize<'r>> FromData<'r> for MsgPack<T> {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
|
|
Loading…
Reference in New Issue