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}