rocket/form/mod.rs
1//! Parsing and validation of HTTP forms and fields.
2//!
3//! See the [forms guide](https://rocket.rs/master/guide/requests#forms) for
4//! general form support documentation.
5//!
6//! # Field Wire Format
7//!
8//! Rocket's field wire format is a flexible, non-self-descriptive, text-based
9//! encoding of arbitrarily nested structure keys and their corresponding
10//! values. The general grammar is:
11//!
12//! ```ebnf
13//! field := name ('=' value)?
14//!
15//! name := key*
16//!
17//! key := indices
18//! | '[' indices ']'
19//! | '.' indices
20//!
21//! indices := index (':' index)*
22//!
23//! index := STRING except ':', ']'
24//!
25//! value := STRING
26//! ```
27//!
28//! Each field name consists of any number of `key`s and at most one `value`.
29//! Keys are delimited by `[` or `.`. A `key` consists of indices delimited by
30//! `:`.
31//!
32//! The meaning of a key or index is type-dependent, hence the format is
33//! non-self-descriptive. _Any_ structure can be described by this format. The
34//! delimiters `.`, `[`, `:`, and `]` have no semantic meaning.
35//!
36//! Some examples of valid fields are:
37//!
38//! * `=`
39//! * `key=value`
40//! * `key[]=value`
41//! * `.0=value`
42//! * `[0]=value`
43//! * `people[].name=Bob`
44//! * `bob.cousin.names[]=Bob`
45//! * `map[k:1]=Bob`
46//! * `people[bob]nickname=Stan`
47//!
48//! See [`FromForm`] for full details on push-parsing and complete examples, and
49//! [`Form`] for how to accept forms in a request handler.
50
51// ## Maps w/named Fields (`struct`)
52//
53// A `struct` with named fields parses values of multiple types, indexed by the
54// name of its fields:
55//
56// ```rust,ignore
57// struct Dog { name: String, barks: bool, friends: Vec<Cat>, }
58// struct Cat { name: String, meows: bool }
59// ```
60//
61// Candidates for parsing into a `Dog` include:
62//
63// * `name=Fido&barks=0`
64//
65// `Dog { "Fido", false }`
66//
67// * `name=Fido&barks=1&friends[0]name=Sally&friends[0]meows=0`
68// `name=Fido&barks=1&friends[0].name=Sally&friends[0].meows=0`
69// `name=Fido&barks=1&friends.0.name=Sally&friends.0.meows=0`
70//
71// `Dog { "Fido", true, vec![Cat { "Sally", false }] }`
72//
73// Parsers for structs are code-generated to proceed as follows:
74//
75// 1. **Initialization.** The context stores parsing options, a `T::Context`
76// for each field of type `T`, and a vector called `extra`.
77//
78// ```rust,ignore
79// struct Context<'v> {
80// opts: FormOptions,
81// field_a: A::Context,
82// field_b: B::Context,
83// /* ... */
84// extra: Vec<FormField<'v>>
85// }
86// ```
87//
88// 2. **Push.** The index of the first key is compared to known field names.
89// If none matches, the index is added to `extra`. Otherwise the key is
90// stripped from the field, and the remaining field is pushed to `T`.
91//
92// ```rust,ignore
93// fn push(this: &mut Self::Context, field: FormField<'v>) {
94// match field.key() {
95// "field_a" => A::push(&mut this.field_a, field.next()),
96// "field_b" => B::push(&mut this.field_b, field.next()),
97// /* ... */
98// _ => this.extra.push(field)
99// }
100// }
101// ```
102//
103// 3. **Finalization.** Every context is finalized; errors and `Ok` values
104// are collected. If parsing is strict and extras is non-empty, an error
105// added to the collection of errors. If there are no errors, all `Ok`
106// values are used to create the `struct`, and the created struct is
107// returned. Otherwise, `Err(errors)` is returned.
108//
109// ```rust,ignore
110// fn finalize(mut this: Self::Context) -> Result<Self, Self::Error> {
111// let mut errors = vec![];
112//
113// let field_a = A::finalize(&mut this.field_a)
114// .map_err(|e| errors.push(e))
115// .map(Some).unwrap_or(None);
116//
117// let field_b = B::finalize(&mut this.field_b)
118// .map_err(|e| errors.push(e))
119// .map(Some).unwrap_or(None);
120//
121// /* .. */
122//
123// if !errors.is_empty() {
124// return Err(Values(errors));
125// } else if this.opts.is_strict() && !this.extra.is_empty() {
126// return Err(Extra(this.extra));
127// } else {
128// // NOTE: All unwraps will succeed since `errors.is_empty()`.
129// Struct {
130// field_a: field_a.unwrap(),
131// field_b: field_b.unwrap(),
132// /* .. */
133// }
134// }
135// }
136// ```
137//
138// ## Sequences: (`Vec<T: FromForm>`)
139//
140// A `Vec<T: FromForm>` invokes `T`'s push-parser on every push, adding instances
141// of `T` to an internal vector. The instance of `T` whose parser is invoked
142// depends on the index of the first key:
143//
144// * if it is the first push, the index differs from the previous, or there is no
145// index, a new `T::Context` is `init`ialized and added to the internal vector
146// * if the index matches the previously seen index, the last initialized
147// `T::Context` is `push`ed to.
148//
149// For instance, the sequentially pushed values `=1`, `=2`, and `=3` for a
150// `Vec<usize>` (or any other integer) is expected to parse as `vec![1, 2, 3]`. The
151// same is true for `[]=1&[]=2&[]=3`. In the first example (`=1&..`), the fields
152// passed to `Vec`'s push-parser (`=1`, ..) have no key and thus no index. In the
153// second example (`[]=1&..`), the key is `[]` (`[]=1`) without an index. In both
154// cases, there is no index. The `Vec` parser takes this to mean that a _new_ `T`
155// should be parsed using the field's value.
156//
157// If, instead, the index was non-empty and equal to the index of the field in the
158// _previous_ push, `Vec` pushes the value to the parser of the previously parsed
159// `T`: `[]=1&[0]=2&[0]=3` results in `vec![1, 2]` and `[0]=1&[0]=2&[]=3` results
160// in `vec![1, 3]` (see [`FromFormValue`]).
161//
162// This generalizes. Consider a `Vec<Vec<usize>>` named `x`, so `x` and an
163// optional `=` are stripped before being passed to `Vec`'s push-parser:
164//
165// * `x=1&x=2&x=3` parses as `vec![vec![1], vec![2], vec![3]]`
166//
167// Every push (`1`, `2`, `3`) has no key, thus no index: a new `T` (here,
168// `Vec<usize>`) is thus initialized for every `push()` and passed the
169// value (here, `1`, `2`, and `3`). Each of these `push`es proceeds
170// recursively: every push again has no key, thus no index, so a new `T` is
171// initialized for every push (now a `usize`), which finally parse as
172// integers `1`, `2`, and `3`.
173//
174// Note: `x=1&x=2&x=3` _also_ can also parse as `vec![1, 2, 3]` when viewed
175// as a `Vec<usize>`; this is the non-self-descriptive part of the format.
176//
177// * `x[]=1&x[]=2&x[]=3` parses as `vec![vec![1], vec![2], vec![3]]`
178//
179// This proceeds nearly identically to the previous example, with the exception
180// that the top-level `Vec` sees the values `[]=1`, `[]=2`, and `[]=3`.
181//
182// * `x[0]=1&x[0]=2&x[]=3` parses as `vec![vec![1, 2], vec![3]]`
183//
184// The top-level `Vec` sees the values `[0]=1`, `[0]=2`, and `[]=3`. The first
185// value results in a new `Vec<usize>` being initialized, as before, which is
186// pushed a `1`. The second value has the same index as the first, `0`, and so
187// `2` is pushed to the previous `T`, the `Vec` which contains the `1`.
188// Finally, the third value has no index, so a new `Vec<usize>` is initialized
189// and pushed a `3`.
190//
191// * `x[0]=1&x[0]=2&x[]=3&x[]=4` parses as `vec![vec![1, 2], vec![3], vec![4]]`
192// * `x[0]=1&x[0]=2&x[1]=3&x[1]=4` parses as `vec![vec![1, 2], vec![3, 4]]`
193//
194// The indexing kind `[]` is purely by convention: the first two examples are
195// equivalent to `x.=1&x.=2`, while the third to `x.0=1&x.0=&x.=3`.
196//
197// The parser proceeds as follows:
198//
199// 1. **Initialization.** The context stores parsing options, the
200// `last_index` encountered in a `push`, an `Option` of a `T::Context` for
201// the `current` value being parsed, a `Vec<T::Errors>` of `errors`, and
202// finally a `Vec<T>` of already parsed `items`.
203//
204// ```rust,ignore
205// struct VecContext<'v, T: FromForm<'v>> {
206// opts: FormOptions,
207// last_index: Index<'v>,
208// current: Option<T::Context>,
209// errors: Vec<T::Error>,
210// items: Vec<T>
211// }
212// ```
213//
214// 2. **Push.** The index of the first key is compared against `last_index`.
215// If it differs, a new context for `T` is created and the previous is
216// finalized. The `Ok` result from finalization is stored in `items` and
217// the `Err` in `errors`. Otherwise the `index` is the same, the `current`
218// context is retrieved, and the field stripped of the current key is
219// pushed to `T`. `last_index` is updated.
220//
221// ```rust,ignore
222// fn push(this: &mut Self::Context, field: FormField<'v>) {
223// if this.last_index != field.index() {
224// this.shift(); // finalize `current`, add to `items`, `errors`
225// let mut context = T::init(this.opts);
226// T::push(&mut context, field.next());
227// this.current = Some(context);
228// } else {
229// let context = this.current.as_mut();
230// T::push(context, field.next())
231// }
232//
233// this.last_index = field.index();
234// }
235// ```
236//
237// 3. **Finalization.** Any `current` context is finalized, storing the `Ok`
238// or `Err` as before. `Ok(items)` is returned if `errors` is empty,
239// otherwise `Err(errors)` is returned.
240//
241// ```rust,ignore
242// fn finalize(mut this: Self::Context) -> Result<Self, Self::Error> {
243// this.shift(); // finalizes `current`, as before.
244// match this.errors.is_empty() {
245// true => Ok(this.items),
246// false => Err(this.errors)
247// }
248// }
249// ```
250//
251// ## Arbitrary Maps (`HashMap<K: FromForm, V: FromForm>`)
252//
253// A `HashMap<K, V>` can be parsed from keys with one index or, for composite
254// key values, such as structures or sequences, multiple indices. We begin with
255// a discussion of the simpler case: non-composite keys.
256//
257// ### Non-Composite Keys
258//
259// A non-composite value can be described by a single field with no indices.
260// Strings and integers are examples of non-composite values. The push-parser
261// for `HashMap<K, V>` for a non-composite `K` uses the index of the first key
262// as the value of `K`; the remainder of the field is pushed to `V`'s parser:
263//
264// 1. **Initialization.** The context stores a column-based representation of
265// `keys` and `values`, a `key_map` from a string key to the column index,
266// an `errors` vector for storing errors as they arise, and the parsing
267// options.
268//
269// ```rust,ignore
270// struct MapContext<'v, K: FromForm<'v>, V: FromForm<'v>> {
271// opts: FormOptions,
272// key_map: HashMap<&'v str, usize>,
273// keys: Vec<K::Context>,
274// values: Vec<V::Context>,
275// errors: Vec<MapError<'v, K::Error, V::Error>>,
276// }
277// ```
278//
279// 2. **Push.** The `key_map` index for the key associated with the index of
280// the first key in the field is retrieved. If such a key has not yet been
281// seen, a new key and value context are created, the key is pushed to
282// `K`'s parser, and the field minus the first key is pushed to `V`'s
283// parser.
284//
285// ```rust,ignore
286// fn push(this: &mut Self::Context, field: FormField<'v>) {
287// let key = field.index();
288// let value_context = match this.key_map.get(Key) {
289// Some(i) => &mut this.values[i],
290// None => {
291// let i = this.keys.len();
292// this.key_map.insert(key, i);
293// this.keys.push(K::init(this.opts));
294// this.values.push(V::init(this.opts));
295// K::push(&mut this.keys[i], key.into());
296// &mut this.values[i]
297// }
298// };
299//
300// V::push(value_context, field.next());
301// }
302// ```
303//
304// 3. **Finalization.** All key and value contexts are finalized; any errors
305// are collected in `errors`. If there are no errors, `keys` and `values`
306// are collected into a `HashMap` and returned. Otherwise, the errors are
307// returned.
308//
309// ```rust,ignore
310// fn finalize(mut this: Self::Context) -> Result<Self, Self::Error> {
311// this.finalize_keys();
312// this.finalize_values();
313// if this.errors.is_empty() {
314// Ok(this.keys.into_iter().zip(this.values.into_iter()).collect())
315// } else {
316// Err(this.errors)
317// }
318// }
319// ```
320//
321// Examples of forms parseable via this parser are:
322//
323// * `x[0].name=Bob&x[0].meows=true`as a `HashMap<usize, Cat>` parses with
324// `0` mapping to `Cat { name: "Bob", meows: true }`
325// * `x[0]name=Bob&x[0]meows=true`as a `HashMap<usize, Cat>` parses just as
326// above.
327// * `x[0]=Bob&x[0]=Sally&x[1]=Craig`as a `HashMap<usize, Vec<String>>`
328// just as `{ 0 => vec!["Bob", "Sally"], 1 => vec!["Craig"] }`.
329//
330// A `HashMap<K, V>` can be thought of as a vector of key-value pairs: `Vec<(K,
331// V)` (row-based) or equivalently, as two vectors of keys and values: `Vec<K>`
332// and `Vec<V>` (column-based). The implication is that indexing into a
333// specific key or value requires _two_ indexes: the first to determine whether
334// a key or value is being indexed to, and the second to determine _which_ key
335// or value. The push-parser for maps thus optionally accepts two indexes for a
336// single key to allow piece-by-piece build-up of arbitrary keys and values.
337//
338// The parser proceeds as follows:
339//
340// 1. **Initialization.** The context stores parsing options, a vector of
341// `key_contexts: Vec<K::Context>`, a vector of `value_contexts:
342// Vec<V::Context>`, a `mapping` from a string index to an integer index
343// into the `contexts`, and a vector of `errors`.
344//
345// 2. **Push.** An index is required; an error is emitted and `push` returns
346// if they field's first key does not contain an index. If the first key
347// contains _one_ index, a new `K::Context` and `V::Context` are created.
348// The key is pushed as the value to `K` and the remaining field as the
349// value to `V`. The key and value are finalized; if both succeed, the key
350// and value are stored in `keys` and `values`; otherwise the error(s) is
351// stored in `errors`.
352//
353// If the first keys contains _two_ indices, the first must starts with
354// `k` or `v`, while the `second` is arbitrary. `mapping` is indexed by
355// `second`; the integer is retrieved. If none exists, new contexts are
356// created an added to `{key,value}_contexts`, and their index is mapped
357// to `second` in `mapping`. If the first index is `k`, the field,
358// stripped of the first key, is pushed to the key's context; the same is
359// done for the value's context is the first index is `v`.
360//
361// 3. **Finalization.** Every context is finalized; errors and `Ok` values
362// are collected.
363
364mod field;
365mod options;
366mod from_form;
367mod from_form_field;
368mod form;
369mod context;
370mod strict;
371mod lenient;
372mod parser;
373mod buffer;
374pub mod validate;
375pub mod name;
376pub mod error;
377
378#[cfg(test)]
379mod tests;
380
381/// Type alias for `Result` with an error type of [`Errors`].
382pub type Result<'v, T> = std::result::Result<T, Errors<'v>>;
383
384#[doc(hidden)]
385pub use rocket_codegen::{FromForm, FromFormField};
386
387#[doc(inline)]
388pub use self::error::{Errors, Error};
389
390#[doc(hidden)]
391pub use self::buffer::{SharedStack, Shareable};
392
393pub use field::*;
394pub use options::*;
395pub use from_form_field::*;
396pub use from_form::*;
397pub use form::*;
398pub use context::*;
399pub use strict::*;
400pub use lenient::*;
401
402#[doc(hidden)]
403pub mod prelude {
404 pub use super::*;
405 pub use super::name::*;
406 pub use super::error::*;
407}