From e5f13792c66a0fe1852a894e7ba0b849c908201e Mon Sep 17 00:00:00 2001 From: Dominic Date: Tue, 5 May 2020 19:50:23 +0200 Subject: [PATCH] doc & test for RequestBody --- gotham_restful/src/types.rs | 27 ++++++++++-- gotham_restful/tests/custom_request_body.rs | 49 +++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 gotham_restful/tests/custom_request_body.rs diff --git a/gotham_restful/src/types.rs b/gotham_restful/src/types.rs index 6c3d635..c858d3b 100644 --- a/gotham_restful/src/types.rs +++ b/gotham_restful/src/types.rs @@ -93,12 +93,31 @@ impl FromBody for T pub struct FromBodyNoError; -/// A type that can be used inside a request body. Implemented for every type that is -/// deserializable with serde. If the `openapi` feature is used, it must also be of type -/// `OpenapiType`. +/** +A type that can be used inside a request body. Implemented for every type that is deserializable +with serde. If the `openapi` feature is used, it must also be of type [`OpenapiType`]. + +If you want a non-deserializable type to be used as a request body, e.g. because you'd like to +get the raw data, you can derive it for your own type. All you need is to have a type implementing +[`FromBody`] and optionally a list of supported media types: + +```rust +# #[macro_use] extern crate gotham_restful; +# use gotham_restful::*; +#[derive(FromBody, RequestBody)] +#[supported_types(mime::IMAGE_GIF, mime::IMAGE_JPEG, mime::IMAGE_PNG)] +struct RawImage { + content: Vec, + content_type: Mime +} +``` + + [`FromBody`]: trait.FromBody.html + [`OpenapiType`]: trait.OpenapiType.html +*/ pub trait RequestBody : ResourceType + FromBody { - /// Return all types that are supported as content types. + /// Return all types that are supported as content types. Use `None` if all types are supported. fn supported_types() -> Option> { None diff --git a/gotham_restful/tests/custom_request_body.rs b/gotham_restful/tests/custom_request_body.rs new file mode 100644 index 0000000..5b108c7 --- /dev/null +++ b/gotham_restful/tests/custom_request_body.rs @@ -0,0 +1,49 @@ +mod custom_request_body +{ + + +use gotham::{ + hyper::header::CONTENT_TYPE, + router::builder::*, + test::TestServer +}; +use gotham_restful::*; +use mime::TEXT_PLAIN; + +const RESPONSE : &[u8] = b"This is the only valid response."; + +#[derive(Resource)] +#[resource(create)] +struct FooResource; + +#[derive(FromBody, RequestBody)] +#[supported_types(TEXT_PLAIN)] +struct Foo { + content: Vec, + content_type: Mime +} + +#[create(FooResource)] +fn create(body : Foo) -> Raw> { + Raw::new(body.content, body.content_type) +} + + +#[test] +fn test() +{ + let server = TestServer::new(build_simple_router(|router| { + router.resource::("foo"); + })).unwrap(); + + let res = server.client() + .post("http://localhost/foo", RESPONSE, TEXT_PLAIN) + .perform().unwrap(); + assert_eq!(res.headers().get(CONTENT_TYPE).unwrap().to_str().unwrap(), "text/plain"); + let res = res.read_body().unwrap(); + let body : &[u8] = res.as_ref(); + assert_eq!(body, RESPONSE); +} + + +}