mirror of
https://github.com/rwf2/Rocket.git
synced 2025-02-16 13:42:05 +00:00
Allow named field generics in 'UriDisplay' derive.
This commit is contained in:
parent
416f42bca7
commit
9d20c57d91
@ -26,6 +26,7 @@ fn generic_bounds_mapper(bound: StaticTokens) -> MapperBuild {
|
||||
|
||||
let bounds = fields.iter()
|
||||
.filter(|f| !f.ty.is_concrete(&generic_idents))
|
||||
.map(|f| &f.field.inner.ty)
|
||||
.map(move |ty| quote_spanned!(ty.span() => #ty: #bound));
|
||||
|
||||
Ok(quote!(#(#bounds,)*))
|
||||
|
@ -1,6 +1,8 @@
|
||||
use rocket::local::asynchronous::Client;
|
||||
use rocket::http::{Status, ContentType, Cookie};
|
||||
use rocket::response::Responder;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::http::Accept;
|
||||
|
||||
#[derive(Responder)]
|
||||
pub enum Foo<'r> {
|
||||
@ -108,15 +110,13 @@ async fn responder_baz() {
|
||||
assert_eq!(r.body_mut().to_string().await.unwrap(), "just a custom");
|
||||
}
|
||||
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
// The bounds `Json<T>: Responder, E: Responder` will be added to the generated
|
||||
// implementation. This would fail to compile otherwise.
|
||||
#[derive(Responder)]
|
||||
enum MyResult<'a, T, E, H> {
|
||||
enum MyResult<'a, T, E, H1, H2> {
|
||||
Ok(Json<T>),
|
||||
#[response(status = 404)]
|
||||
Err(E, H),
|
||||
Err(E, H1, H2),
|
||||
#[response(status = 500)]
|
||||
Other(&'a str),
|
||||
}
|
||||
@ -127,19 +127,19 @@ async fn generic_responder() {
|
||||
let local_req = client.get("/");
|
||||
let req = local_req.inner();
|
||||
|
||||
let v: MyResult<_, (), ContentType> = MyResult::Ok(Json("hi"));
|
||||
let v: MyResult<_, (), ContentType, Cookie<'static>> = 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 v: MyResult<(), &[u8], _, _> = MyResult::Err(&[7, 13, 23], ContentType::JPEG, Accept::Text);
|
||||
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], ContentType> = MyResult::Other("beep beep");
|
||||
let v: MyResult<(), &[u8], ContentType, Accept> = 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);
|
||||
|
@ -10,6 +10,19 @@ macro_rules! assert_uri_display_query {
|
||||
)
|
||||
}
|
||||
|
||||
macro_rules! assert_query_form_roundtrip {
|
||||
($T:ty, $v:expr) => ({
|
||||
use rocket::form::{Form, Strict};
|
||||
use rocket::http::RawStr;
|
||||
|
||||
let v = $v;
|
||||
let string = format!("{}", &v as &dyn UriDisplay<Query>);
|
||||
let raw = RawStr::new(&string);
|
||||
let value = Form::<Strict<$T>>::parse_encoded(raw).map(|s| s.into_inner());
|
||||
assert_eq!(value.expect("form parse"), v);
|
||||
})
|
||||
}
|
||||
|
||||
macro_rules! assert_query_value_roundtrip {
|
||||
($T:ty, $v:expr) => ({
|
||||
use rocket::form::{Form, Strict};
|
||||
@ -213,12 +226,12 @@ fn uri_display_path() {
|
||||
fn uri_display_serde() {
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, UriDisplayQuery, Deserialize, Serialize)]
|
||||
#[derive(Debug, PartialEq, Clone, FromForm, UriDisplayQuery, Deserialize, Serialize)]
|
||||
#[serde(crate = "rocket::serde")]
|
||||
struct Bam {
|
||||
foo: String,
|
||||
bar: Option<usize>,
|
||||
baz: Result<String, usize>,
|
||||
baz: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, FromForm, UriDisplayQuery)]
|
||||
@ -227,11 +240,39 @@ fn uri_display_serde() {
|
||||
let bam = Bam {
|
||||
foo: "hi[]=there.baz !?".into(),
|
||||
bar: None,
|
||||
baz: Ok("what is baz, anyway?".into()),
|
||||
baz: true,
|
||||
};
|
||||
|
||||
assert_query_form_roundtrip!(Bam, bam.clone());
|
||||
|
||||
assert_query_value_roundtrip!(JsonFoo, JsonFoo(Json(bam.clone())));
|
||||
|
||||
// FIXME: https://github.com/rust-lang/rust/issues/86706
|
||||
#[allow(private_in_public)]
|
||||
#[derive(Debug, PartialEq, Clone, FromForm, UriDisplayQuery)]
|
||||
struct Q<T>(Json<T>);
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, FromForm, UriDisplayQuery)]
|
||||
pub struct Generic<A, B> {
|
||||
a: Q<A>,
|
||||
b: Q<B>,
|
||||
c: Q<A>,
|
||||
}
|
||||
|
||||
assert_query_form_roundtrip!(Generic<usize, String>, Generic {
|
||||
a: Q(Json(133)),
|
||||
b: Q(Json("hello, world#rocket!".into())),
|
||||
c: Q(Json(40486)),
|
||||
});
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, FromForm, UriDisplayQuery)]
|
||||
// This is here to ensure we don't warn, which we can't test with trybuild.
|
||||
pub struct GenericBorrow<'a, A: ?Sized, B: 'a> {
|
||||
a: Q<&'a A>,
|
||||
b: Q<B>,
|
||||
c: Q<&'a A>,
|
||||
}
|
||||
|
||||
// TODO: This requires `MsgPack` to parse from value form fields.
|
||||
//
|
||||
// use rocket::serde::msgpack::MsgPack;
|
||||
|
Loading…
Reference in New Issue
Block a user