tower_web/extract/
mod.rs

1//! Extract data from the HTTP request.
2//!
3//! The [`Extract`] trait is implemented by types that can be constructed by
4//! using data from an HTTP request. Resource method argument types must
5//! implement [`Extract`]. This is how `impl_web!` is able to instantiate them
6//! using the request. See [library level][lib] documentation for more details.
7//!
8//! Currently, [`Extract`] implementations are provided for the following types:
9//!
10//! * [`Bytes`](https://docs.rs/bytes/0.4/bytes/struct.Bytes.html)
11//! * [`Option`](https://doc.rust-lang.org/std/option/enum.Option.html)
12//! * [`PathBuf`](https://doc.rust-lang.org/std/path/struct.PathBuf.html)
13//! * [`String`](https://doc.rust-lang.org/std/string/struct.String.html)
14//! * [`Vec<u8>`](https://doc.rust-lang.org/std/vec/struct.Vec.html)
15//!
16//! More implementations can be added by submitting a PR.
17//!
18//! Also, [`Extract`] can be implemented for custom types by using the
19//! [`derive(Extract)`] proc macro. See [library level][lib] documentation for
20//! more details.
21//!
22//! [`Extract`]: trait.Extract.html
23//! [lib]: ../index.html
24
25mod bytes;
26mod context;
27mod error;
28mod immediate;
29mod num;
30pub mod option;
31mod pathbuf;
32#[doc(hidden)]
33pub mod serde;
34mod str;
35mod osstring;
36pub mod http_date_time;
37
38pub use self::error::Error;
39pub use self::context::Context;
40pub use self::immediate::Immediate;
41
42use codegen::CallSite;
43use util::BufStream;
44
45use futures::Poll;
46
47/// Extract a value from an HTTP request.
48///
49/// The extracted value does not need to be produced immediately.
50/// Implementations of `Extract` are able to perform asynchronous processing.
51///
52/// The trait is generic over `B: BufStream`, which represents the HTTP request
53/// body stream.
54pub trait Extract<B: BufStream>: 'static + Sized {
55    /// The future representing the completion of the extraction logic.
56    type Future: ExtractFuture<Item = Self>;
57
58    /// Extract the argument from the HTTP request.
59    ///
60    /// This function is not provide the HTTP request body. Implementations of
61    /// this function must ensure that the request HEAD (request URI and
62    /// headers) are sufficient for extracting the value.
63    fn extract(context: &Context) -> Self::Future;
64
65    /// Extract the argument using the HTTP request body.
66    ///
67    /// Doing so will usually involve deserializing the contents of the HTTP
68    /// request body to the target value being extracted.
69    fn extract_body(context: &Context, body: B) -> Self::Future {
70        drop((context, body));
71        panic!("The default implementation of `Extract::extract_body` should never be called")
72    }
73
74    /// Returns `true` if extracting the type requires `body`.
75    ///
76    /// Only a single resource method argument may extract using the HTTP
77    /// request body. This function allows enforcing this requirement.
78    fn requires_body(callsite: &CallSite) -> bool {
79        drop(callsite);
80        false
81    }
82}
83
84/// Future representing the completion of extracting a value from a request
85///
86/// Implementations are expected to advance to a state where `extract` will
87/// succeed. This is done by performing any asynchronous processing when `poll`
88/// is called and usually stashing the extracted value internally until
89/// `extract` is called.
90///
91/// `extract` must not be called until `poll` returns `Ok(Ready(()))`.
92pub trait ExtractFuture {
93    /// The argument extracted from the request.
94    type Item;
95
96    /// Returns `Ok(Ready(()))` when `extract()` can be called. If `NotReady` is
97    /// returned, the current task is registered for wakeup.
98    fn poll(&mut self) -> Poll<(), Error>;
99
100    /// Consume `self` and return the value extracted from the HTTP request.
101    fn extract(self) -> Self::Item;
102}