diff --git a/core/lib/src/data/from_data.rs b/core/lib/src/data/from_data.rs index c5cdb75f..46108175 100644 --- a/core/lib/src/data/from_data.rs +++ b/core/lib/src/data/from_data.rs @@ -1,4 +1,3 @@ -use std::io::{self, Read}; use std::borrow::Borrow; use outcome::{self, IntoOutcome}; @@ -289,6 +288,9 @@ pub type Transformed<'a, T> = /// /// * **String** /// +/// **Note:** _An implementation of `FromData` for `String` is only available +/// when compiling in debug mode!_ +/// /// Reads the entire request body into a `String`. If reading fails, returns /// a `Failure` with the corresponding `io::Error`. /// @@ -299,6 +301,9 @@ pub type Transformed<'a, T> = /// /// * **Vec<u8>** /// +/// **Note:** _An implementation of `FromData` for `Vec` is only +/// available when compiling in debug mode!_ +/// /// Reads the entire request body into a `Vec`. If reading fails, /// returns a `Failure` with the corresponding `io::Error`. /// @@ -307,7 +312,7 @@ pub type Transformed<'a, T> = /// memory; since the user controls the size of the body, this is an obvious /// vector for a denial of service attack. /// -/// # Simple `FromData` +/// # Simplified `FromData` /// /// For an example of a type that wouldn't require transformation, see the /// [`FromDataSimple`] documentation. @@ -398,15 +403,15 @@ impl<'f> FromData<'f> for Data { /// A simple, less complex variant of [`FromData`]. /// /// When transformation of incoming data isn't required, data guards should -/// implement this trait instead of [`FromData`]. For a description of data -/// guards, see the [`FromData`] documentation. +/// implement this trait instead of [`FromData`]. Any type that implements +/// `FromDataSimple` automatically implements `FromData`. For a description of +/// data guards, see the [`FromData`] documentation. /// /// # Example /// /// Say that you have a custom type, `Person`: /// /// ```rust -/// # #[allow(dead_code)] /// struct Person { /// name: String, /// age: u16 @@ -556,6 +561,9 @@ impl<'a, T: FromData<'a> + 'a> FromData<'a> for Option { } } +#[cfg(debug_assertions)] +use std::io::{self, Read}; + #[cfg(debug_assertions)] impl FromDataSimple for String { type Error = io::Error; diff --git a/examples/content_types/src/main.rs b/examples/content_types/src/main.rs index 83c6bcdf..419e4d7a 100644 --- a/examples/content_types/src/main.rs +++ b/examples/content_types/src/main.rs @@ -2,12 +2,14 @@ #![plugin(rocket_codegen)] #[macro_use] extern crate rocket; -extern crate serde_json; #[macro_use] extern crate serde_derive; +extern crate serde_json; #[cfg(test)] mod tests; -use rocket::{Request, response::content}; +use std::io::{self, Read}; + +use rocket::{Request, response::content, data::Data}; #[derive(Debug, Serialize, Deserialize)] struct Person { @@ -28,10 +30,16 @@ fn get_hello(name: String, age: u8) -> content::Json { // In a `POST` request and all other payload supporting request types, the // content type is matched against the `format` in the route attribute. -#[post("/", format = "plain", data = "")] -fn post_hello(age: u8, name: String) -> content::Json { +// +// Note that `content::Json` simply sets the content-type to `application/json`. +// In a real application, we wouldn't use `serde_json` directly; instead, we'd +// use `contrib::Json` to automatically serialize a type into JSON. +#[post("/", format = "plain", data = "")] +fn post_hello(age: u8, name_data: Data) -> io::Result> { + let mut name = String::with_capacity(32); + name_data.open().take(32).read_to_string(&mut name)?; let person = Person { name: name, age: age, }; - content::Json(serde_json::to_string(&person).unwrap()) + Ok(content::Json(serde_json::to_string(&person).unwrap())) } #[catch(404)]