Derive Macro rocket_codegen::Responder
source · #[derive(Responder)]
{
// Attributes available to this derive:
#[response]
}
Expand description
Derive for the Responder
trait.
The Responder
derive can be applied to enums and structs with named
fields. When applied to enums, variants must have at least one field. When
applied to structs, the struct must have at least one field.
#[derive(Responder)]
enum MyResponderA {
A(String),
B(File, ContentType),
}
#[derive(Responder)]
struct MyResponderB {
inner: OtherResponder,
header: ContentType,
}
Semantics
The derive generates an implementation of the Responder
trait for the
decorated enum or structure. The derive uses the first field of a variant
or structure to generate a Response
. As such, the type of the first
field must implement Responder
. The remaining fields of a variant or
structure are set as headers in the produced Response
using
Response::set_header()
. As such, every other field (unless explicitly
ignored, explained next) must implement Into<Header>
.
Except for the first field, fields decorated with #[response(ignore)]
are
ignored by the derive:
#[derive(Responder)]
enum MyResponder {
A(String),
B(File, ContentType, #[response(ignore)] Other),
}
#[derive(Responder)]
struct MyOtherResponder {
inner: NamedFile,
header: ContentType,
#[response(ignore)]
other: Other,
}
Decorating the first field with #[response(ignore)]
has no effect.
Field Attribute
Additionally, the response
attribute can be used on named structures and
enum variants to override the status and/or content-type of the Response
produced by the generated implementation. The response
attribute used in
these positions has the following grammar:
response := parameter (',' parameter)?
parameter := 'status' '=' STATUS
| 'content_type' '=' CONTENT_TYPE
STATUS := unsigned integer >= 100 and < 600
CONTENT_TYPE := string literal, as defined by Rust, identifying a valid
Content-Type, as defined by Rocket
It can be used as follows:
#[derive(Responder)]
enum Error {
#[response(status = 500, content_type = "json")]
A(String),
#[response(status = 404)]
B(NamedFile, ContentType),
}
#[derive(Responder)]
#[response(status = 400)]
struct MyResponder {
inner: InnerResponder,
header: ContentType,
#[response(ignore)]
other: Other,
}
The attribute accepts two key/value pairs: status
and content_type
. The
value of status
must be an unsigned integer representing a valid status
code. The Response
produced from the generated implementation will have
its status overridden to this value.
The value of content_type
must be a valid media-type in top/sub
form or
shorthand
form. Examples include:
"text/html"
"application/x-custom"
"html"
"json"
"plain"
"binary"
See ContentType::parse_flexible()
for a full list of available
shorthands. The Response
produced from the generated implementation will
have its content-type overridden to this value.
Generics
The derive accepts any number of type generics and at most one lifetime
generic. If a type generic is present and the generic is used in the first
field of a structure, the generated implementation will require a bound of
Responder<'r, 'o>
for the field type containing the generic. In all other
fields, unless ignores, a bound of Into<Header<'o>
is added.
For example, for a struct struct Foo<T, H>(Json<T>, H)
, the derive adds:
Json<T>: Responder<'r, 'o>
H: Into<Header<'o>>
use rocket::serde::Serialize;
use rocket::serde::json::Json;
use rocket::http::ContentType;
use rocket::response::Responder;
// The bound `T: Responder` will be added.
#[derive(Responder)]
#[response(status = 404, content_type = "html")]
struct NotFoundHtml<T>(T);
// The bound `Json<T>: Responder` will be added.
#[derive(Responder)]
struct NotFoundJson<T>(Json<T>);
// The bounds `Json<T>: Responder, E: Responder` will be added.
#[derive(Responder)]
enum MyResult<T, E> {
Ok(Json<T>),
#[response(status = 404)]
Err(E, ContentType)
}
If a lifetime generic is present, it will be replaced with 'o
in the
generated implementation impl Responder<'r, 'o>
:
// Generates `impl<'r, 'o> Responder<'r, 'o> for NotFoundHtmlString<'o>`.
#[derive(Responder)]
#[response(status = 404, content_type = "html")]
struct NotFoundHtmlString<'a>(&'a str);
Both type generics and lifetime generic may be used:
#[derive(Responder)]
struct SomeResult<'o, T>(Result<T, &'o str>);