mirror of https://github.com/rwf2/Rocket.git
Fixup forms documentation for new features.
This commit is contained in:
parent
aefa2f1494
commit
0e82eb0b31
|
@ -102,7 +102,7 @@
|
||||||
//! address = "0.0.0.0"
|
//! address = "0.0.0.0"
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! ## Environment Variables
|
//! ### Environment Variables
|
||||||
//!
|
//!
|
||||||
//! All configuration parameters, including extras, can be overridden through
|
//! All configuration parameters, including extras, can be overridden through
|
||||||
//! environment variables. To override the configuration parameter `{param}`,
|
//! environment variables. To override the configuration parameter `{param}`,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use memchr::memchr2;
|
use memchr::memchr2;
|
||||||
|
|
||||||
/// Iterator over the key/value pairs of a given HTTP form string. You'll likely
|
/// Iterator over the key/value pairs of a given HTTP form string.
|
||||||
/// want to use this if you're implementing [FromForm](trait.FromForm.html)
|
|
||||||
/// manually, for whatever reason, by iterating over the items in `form_string`.
|
|
||||||
///
|
///
|
||||||
/// **Note:** The returned key/value pairs are _not_ URL decoded. To URL decode
|
/// **Note:** The returned key/value pairs are _not_ URL decoded. To URL decode
|
||||||
/// the raw strings, use `String::from_form_value`:
|
/// the raw strings, use `String::from_form_value`:
|
||||||
|
@ -21,6 +19,23 @@ use memchr::memchr2;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
|
/// # Completion
|
||||||
|
///
|
||||||
|
/// The iterator keeps track of whether the form string was parsed to completion
|
||||||
|
/// to determine if the form string was malformed. The iterator can be queried
|
||||||
|
/// for completion via the [completed](#method.completed) method, which returns
|
||||||
|
/// `true` if the iterator parsed the entire string that was passed to it. The
|
||||||
|
/// iterator can also attempt to parse any remaining contents via
|
||||||
|
/// [exhausted](#method.exhausted); this method returns `true` if exhaustion
|
||||||
|
/// succeeded.
|
||||||
|
///
|
||||||
|
/// This iterator guarantees that all valid form strings are parsed to
|
||||||
|
/// completion. The iterator attempts to be lenient. In particular, it allows
|
||||||
|
/// the following oddball behavior:
|
||||||
|
///
|
||||||
|
/// * A single trailing `&` character is allowed.
|
||||||
|
/// * Empty values are allowed.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// `FormItems` can be used directly as an iterator:
|
/// `FormItems` can be used directly as an iterator:
|
||||||
|
@ -53,11 +68,71 @@ pub struct FormItems<'f> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'f> FormItems<'f> {
|
impl<'f> FormItems<'f> {
|
||||||
|
/// Returns `true` if the form string was parsed to completion. Returns
|
||||||
|
/// `false` otherwise. All valid form strings will parse to completion,
|
||||||
|
/// while invalid form strings will not.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// A valid form string parses to completion:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::request::FormItems;
|
||||||
|
///
|
||||||
|
/// let mut items = FormItems::from("a=b&c=d");
|
||||||
|
/// let key_values: Vec<_> = items.by_ref().collect();
|
||||||
|
///
|
||||||
|
/// assert_eq!(key_values.len(), 2);
|
||||||
|
/// assert_eq!(items.completed(), true);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// In invalid form string does not parse to completion:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::request::FormItems;
|
||||||
|
///
|
||||||
|
/// let mut items = FormItems::from("a=b&=d");
|
||||||
|
/// let key_values: Vec<_> = items.by_ref().collect();
|
||||||
|
///
|
||||||
|
/// assert_eq!(key_values.len(), 1);
|
||||||
|
/// assert_eq!(items.completed(), false);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn completed(&self) -> bool {
|
pub fn completed(&self) -> bool {
|
||||||
self.next_index >= self.string.len()
|
self.next_index >= self.string.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parses all remaining key/value pairs and returns `true` if parsing ran
|
||||||
|
/// to completion. All valid form strings will parse to completion, while
|
||||||
|
/// invalid form strings will not.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// A valid form string can be exhausted:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::request::FormItems;
|
||||||
|
///
|
||||||
|
/// let mut items = FormItems::from("a=b&c=d");
|
||||||
|
///
|
||||||
|
/// assert!(items.next().is_some());
|
||||||
|
/// assert_eq!(items.completed(), false);
|
||||||
|
/// assert_eq!(items.exhausted(), true);
|
||||||
|
/// assert_eq!(items.completed(), true);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// An invalid form string cannot be exhausted:
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::request::FormItems;
|
||||||
|
///
|
||||||
|
/// let mut items = FormItems::from("a=b&=d");
|
||||||
|
///
|
||||||
|
/// assert!(items.next().is_some());
|
||||||
|
/// assert_eq!(items.completed(), false);
|
||||||
|
/// assert_eq!(items.exhausted(), false);
|
||||||
|
/// assert_eq!(items.completed(), false);
|
||||||
|
/// ```
|
||||||
pub fn exhausted(&mut self) -> bool {
|
pub fn exhausted(&mut self) -> bool {
|
||||||
while let Some(_) = self.next() { }
|
while let Some(_) = self.next() { }
|
||||||
self.completed()
|
self.completed()
|
||||||
|
@ -69,6 +144,28 @@ impl<'f> FormItems<'f> {
|
||||||
self.next_index = self.string.len()
|
self.next_index = self.string.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieves the original string being parsed by this iterator. The string
|
||||||
|
/// returned by this method does not change, regardless of the status of the
|
||||||
|
/// iterator.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use rocket::request::FormItems;
|
||||||
|
///
|
||||||
|
/// let form_string = "a=b&c=d";
|
||||||
|
/// let mut items = FormItems::from(form_string);
|
||||||
|
/// assert_eq!(items.inner_str(), form_string);
|
||||||
|
///
|
||||||
|
/// assert!(items.next().is_some());
|
||||||
|
/// assert_eq!(items.inner_str(), form_string);
|
||||||
|
///
|
||||||
|
/// assert!(items.next().is_some());
|
||||||
|
/// assert_eq!(items.inner_str(), form_string);
|
||||||
|
///
|
||||||
|
/// assert!(items.next().is_none());
|
||||||
|
/// assert_eq!(items.inner_str(), form_string);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inner_str(&self) -> &'f str {
|
pub fn inner_str(&self) -> &'f str {
|
||||||
self.string
|
self.string
|
||||||
|
@ -76,6 +173,8 @@ impl<'f> FormItems<'f> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'f> From<&'f str> for FormItems<'f> {
|
impl<'f> From<&'f str> for FormItems<'f> {
|
||||||
|
/// Returns an iterator over the key/value pairs in the
|
||||||
|
/// `x-www-form-urlencoded` form `string`.
|
||||||
fn from(string: &'f str) -> FormItems<'f> {
|
fn from(string: &'f str) -> FormItems<'f> {
|
||||||
FormItems {
|
FormItems {
|
||||||
string: string,
|
string: string,
|
||||||
|
@ -159,6 +258,7 @@ mod test {
|
||||||
check_form!("a=b&a=", &[("a", "b"), ("a", "")]);
|
check_form!("a=b&a=", &[("a", "b"), ("a", "")]);
|
||||||
|
|
||||||
check_form!(@bad "user=&password");
|
check_form!(@bad "user=&password");
|
||||||
|
check_form!(@bad "user=x&&");
|
||||||
check_form!(@bad "a=b&a");
|
check_form!(@bad "a=b&a");
|
||||||
check_form!(@bad "=");
|
check_form!(@bad "=");
|
||||||
check_form!(@bad "&");
|
check_form!(@bad "&");
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use request::FormItems;
|
use request::FormItems;
|
||||||
|
|
||||||
/// Trait to create an instance of some type from an HTTP form. The
|
/// Trait to create an instance of some type from an HTTP form.
|
||||||
/// [Form](struct.Form.html) type requires that its generic parameter implements
|
/// [Form](struct.Form.html) requires its generic type to implement this trait.
|
||||||
/// this trait.
|
|
||||||
///
|
///
|
||||||
/// This trait can be automatically derived via the
|
/// This trait can be automatically derived via the
|
||||||
/// [rocket_codegen](/rocket_codegen) plugin:
|
/// [rocket_codegen](/rocket_codegen) plugin:
|
||||||
|
@ -44,17 +43,16 @@ use request::FormItems;
|
||||||
///
|
///
|
||||||
/// # Implementing
|
/// # Implementing
|
||||||
///
|
///
|
||||||
/// If you implement `FormForm` yourself, use the
|
/// An implementation of `FromForm` uses the [FormItems](struct.FormItems.html)
|
||||||
/// [FormItems](struct.FormItems.html) iterator to iterate through the form
|
/// iterator to iterate through the raw form key/value pairs. Be aware that form
|
||||||
/// key/value pairs. Be aware that form fields that are typically hidden from
|
/// fields that are typically hidden from your application, such as `_method`,
|
||||||
/// your application, such as `_method`, will be present while iterating.
|
/// will be present while iterating.
|
||||||
pub trait FromForm<'f>: Sized {
|
pub trait FromForm<'f>: Sized {
|
||||||
/// The associated error to be returned when parsing fails.
|
/// The associated error to be returned when parsing fails.
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
/// Parses an instance of `Self` from a raw HTTP form string
|
/// Parses an instance of `Self` from the form items or returns an `Error`
|
||||||
/// (`application/x-www-form-urlencoded data`) or returns an `Error` if one
|
/// if one cannot be parsed.
|
||||||
/// cannot be parsed.
|
|
||||||
fn from_form_items(form_items: &mut FormItems<'f>) -> Result<Self, Self::Error>;
|
fn from_form_items(form_items: &mut FormItems<'f>) -> Result<Self, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ use outcome::Outcome::*;
|
||||||
/// A `FromData` type for parsing `FromForm` types.
|
/// A `FromData` type for parsing `FromForm` types.
|
||||||
///
|
///
|
||||||
/// This type implements the `FromData` trait. It provides a generic means to
|
/// This type implements the `FromData` trait. It provides a generic means to
|
||||||
/// parse arbitrary structure from incoming form data.
|
/// parse arbitrary structures from incoming form data.
|
||||||
///
|
///
|
||||||
/// # Usage
|
/// # Usage
|
||||||
///
|
///
|
||||||
|
@ -251,12 +251,17 @@ impl<'f, T: FromForm<'f> + Debug + 'f> Debug for Form<'f, T> {
|
||||||
///
|
///
|
||||||
/// If the content type of the request data is not
|
/// If the content type of the request data is not
|
||||||
/// `application/x-www-form-urlencoded`, `Forward`s the request. If the form
|
/// `application/x-www-form-urlencoded`, `Forward`s the request. If the form
|
||||||
/// data cannot be parsed into a `T` or reading the incoming stream failed,
|
/// data cannot be parsed into a `T`, a `Failure` with status code
|
||||||
/// returns a `Failure` with the raw form string (if avaialble).
|
/// `UnprocessableEntity` is returned. If the form string is malformed, a
|
||||||
|
/// `Failure` with status code `BadRequest` is returned. Finally, if reading the
|
||||||
|
/// incoming stream fails, returns a `Failure` with status code
|
||||||
|
/// `InternalServerError`. In all failure cases, the raw form string is returned
|
||||||
|
/// if it was able to be retrieved from the incoming stream.
|
||||||
///
|
///
|
||||||
/// All relevant warnings and errors are written to the console in Rocket
|
/// All relevant warnings and errors are written to the console in Rocket
|
||||||
/// logging format.
|
/// logging format.
|
||||||
impl<'f, T: FromForm<'f>> FromData for Form<'f, T> where T::Error: Debug {
|
impl<'f, T: FromForm<'f>> FromData for Form<'f, T> where T::Error: Debug {
|
||||||
|
/// The raw form string, if it was able to be retrieved from the request.
|
||||||
type Error = Option<String>;
|
type Error = Option<String>;
|
||||||
|
|
||||||
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
|
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, Self::Error> {
|
||||||
|
|
|
@ -71,7 +71,7 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
|
||||||
/// Rocket implements `FromRequest` for several built-in types. Their behavior
|
/// Rocket implements `FromRequest` for several built-in types. Their behavior
|
||||||
/// is documented here.
|
/// is documented here.
|
||||||
///
|
///
|
||||||
/// * **URI**
|
/// * **&URI**
|
||||||
///
|
///
|
||||||
/// Extracts the [URI](/rocket/http/uri/struct.URI.html) from the incoming
|
/// Extracts the [URI](/rocket/http/uri/struct.URI.html) from the incoming
|
||||||
/// request.
|
/// request.
|
||||||
|
|
|
@ -12,5 +12,6 @@ pub use self::param::{FromParam, FromSegments};
|
||||||
pub use self::form::{Form, FromForm, FromFormValue, FormItems};
|
pub use self::form::{Form, FromForm, FromFormValue, FormItems};
|
||||||
pub use self::state::State;
|
pub use self::state::State;
|
||||||
|
|
||||||
/// Type alias to retrieve flash messages from a request.
|
/// Type alias to retrieve [Flash](/rocket/response/struct.Flash.html) messages
|
||||||
|
/// from a request.
|
||||||
pub type FlashMessage = ::response::Flash<()>;
|
pub type FlashMessage = ::response::Flash<()>;
|
||||||
|
|
|
@ -20,7 +20,7 @@ use http::hyper;
|
||||||
///
|
///
|
||||||
/// This should be used sparingly in Rocket applications. In particular, it
|
/// This should be used sparingly in Rocket applications. In particular, it
|
||||||
/// should likely only be used when writing
|
/// should likely only be used when writing
|
||||||
/// [FromRequest](/rocket/request/struct.Request.html) implementations. It
|
/// [FromRequest](/rocket/request/trait.FromRequest.html) implementations. It
|
||||||
/// contains all of the information for a given web request except for the body
|
/// contains all of the information for a given web request except for the body
|
||||||
/// data. This includes the HTTP method, URI, cookies, headers, and more.
|
/// data. This includes the HTTP method, URI, cookies, headers, and more.
|
||||||
pub struct Request<'r> {
|
pub struct Request<'r> {
|
||||||
|
@ -319,7 +319,8 @@ impl<'r> Request<'r> {
|
||||||
*self.params.borrow_mut() = route.get_param_indexes(self.uri());
|
*self.params.borrow_mut() = route.get_param_indexes(self.uri());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `n`th path parameter as a string, if it exists.
|
/// Get the `n`th path parameter as a string, if it exists. This is used by
|
||||||
|
/// codegen.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn get_param_str(&self, n: usize) -> Option<&str> {
|
pub fn get_param_str(&self, n: usize) -> Option<&str> {
|
||||||
let params = self.params.borrow();
|
let params = self.params.borrow();
|
||||||
|
@ -364,7 +365,7 @@ impl<'r> Request<'r> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the segments beginning at the `n`th dynamic parameter, if they
|
/// Get the segments beginning at the `n`th dynamic parameter, if they
|
||||||
/// exist.
|
/// exist. Used by codegen.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub fn get_raw_segments(&self, n: usize) -> Option<Segments> {
|
pub fn get_raw_segments(&self, n: usize) -> Option<Segments> {
|
||||||
let params = self.params.borrow();
|
let params = self.params.borrow();
|
||||||
|
|
|
@ -11,7 +11,7 @@ use http::Status;
|
||||||
/// number of handlers. A value for the given type must previously have been
|
/// number of handlers. A value for the given type must previously have been
|
||||||
/// registered to be managed by Rocket via the
|
/// registered to be managed by Rocket via the
|
||||||
/// [manage](/rocket/struct.Rocket.html#method.manage) method. The type being
|
/// [manage](/rocket/struct.Rocket.html#method.manage) method. The type being
|
||||||
/// managed must be thread safe and sendable across thread boundaries. In otehr
|
/// managed must be thread safe and sendable across thread boundaries. In other
|
||||||
/// words, it must implement `Send + Sync + 'static`.
|
/// words, it must implement `Send + Sync + 'static`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
|
Loading…
Reference in New Issue