1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
//! # Serve the web
//!
//! Tide is a friendly HTTP server built for casual Rustaceans and veterans alike. It's completely
//! modular, and built directly for `async/await`. Whether it's a quick webhook, or an L7 load
//! balancer, Tide will make it work.
//!
//! # Features
//!
//! - __Fast:__ Written in Rust, and built on Futures, Tide is incredibly efficient.
//! - __Friendly:__ With thorough documentation, and a complete API, Tide helps cover your every
//!     need.
//! - __Minimal:__ With only a few concepts to learn, Tide is easy to pick up and become productive
//!     with.
//!
//! # Getting started
//!
//! Add two dependencies to your project's `Cargo.toml` file: `tide` itself, and `async-std` with the feature `attributes` enabled:
//! ```toml
//! # Example, use the version numbers you need
//! tide = "0.7.0"
//! async-std = { version = "1.5.0", features = ["attributes"] }
//!```
//!
//! # Examples
//!
//! __hello world__
//! ```no_run
//! # use async_std::task::block_on;
//! # fn main() -> Result<(), std::io::Error> { block_on(async {
//! #
//! let mut app = tide::new();
//! app.at("/").get(|_| async { Ok("Hello, world!") });
//! app.listen("127.0.0.1:8080").await?;
//! #
//! # Ok(()) }) }
//! ```
//!
//! __echo server__
//! ```no_run
//! # use async_std::task::block_on;
//! # fn main() -> Result<(), std::io::Error> { block_on(async {
//! #
//! let mut app = tide::new();
//! app.at("/").get(|req| async { Ok(req) });
//! app.listen("127.0.0.1:8080").await?;
//! #
//! # Ok(()) }) }
//! ````
//!
//! __send and receive json__
//! ```no_run
//! # use async_std::task::block_on;
//! # fn main() -> Result<(), std::io::Error> { block_on(async {
//! # use tide::{Body, Request, Response};
//! #
//! #[derive(Debug, serde::Deserialize, serde::Serialize)]
//! struct Counter { count: usize }
//!
//! let mut app = tide::new();
//! app.at("/").get(|mut req: Request<()>| async move {
//!    let mut counter: Counter = req.body_json().await?;
//!    println!("count is {}", counter.count);
//!    counter.count += 1;
//!    let mut res = Response::new(200);
//!    res.set_body(Body::from_json(&counter)?);
//!    Ok(res)
//! });
//! app.listen("127.0.0.1:8080").await?;
//! #
//! # Ok(()) }) }
//! ```
//!
//! # Concepts
//!
//! ## Request-Response
//!
//! Each Tide endpoint takes a [`Request`] and returns a [`Response`]. Because async functions
//! allow us to wait without blocking, this makes Tide feel similar to synchronous servers. Except
//! it's incredibly efficient.
//!
//! ```txt
//! async fn endpoint(req: Request) -> Result;
//! ```
//!
//! ## Middleware
//!
//! Middleware wrap each request and response pair, allowing code to be run before the endpoint,
//! and after each endpoint. Additionally each handler can choose to never yield to the endpoint
//! and abort early. This is useful for e.g. authentication middleware. Tide's middleware works
//! like a stack. A simplified example of the logger middleware is something like this:
//!
//! ```ignore
//! async fn log(req: Request, next: Next) -> tide::Result {
//!     println!("Incoming request from {} on url {}", req.peer_addr(), req.url());
//!     let res = next().await?;
//!     println!("Outgoing response with status {}", res.status());
//!     res
//! }
//! ```
//!
//! As a new request comes in, we perform some logic. Then we yield to the next
//! middleware (or endpoint, we don't know when we yield to `next`), and once that's
//! done, we return the Response. We can decide to not yield to `next` at any stage,
//! and abort early. This can then be used in applications using the [`Server::middleware`]
//! method.
//!
//! ## State
//!
//! Middleware often needs to share values with the endpoint. This is done through "request scoped
//! state".  Request scoped state is built using a typemap that's available through
//! [`Request::ext`].
//!
//! If the endpoint needs to share values with middleware, response scoped state can be set via
//! [`Response::insert_ext`] and is available through [`Response::ext`].
//!
//! Application scoped state is used when a complete application needs access to a particular
//! value. Examples of this include: database connections, websocket connections, or
//! network-enabled config. Every `Request<State>` has an inner value that must
//! implement `Send + Sync + Clone`, and can thus freely be shared between requests.
//!
//! By default `tide::new` will use `()` as the shared state. But if you want to
//! create a new app with shared state you can use the [`with_state`] function.
//!
//! ## Extension Traits
//!
//! Sometimes having application and request scoped context can require a bit of setup. There are
//! cases where it'd be nice if things were a little easier. This is why Tide
//! encourages people to write _extension traits_.
//!
//! By using an _extension trait_ you can extend [`Request`] or [`Response`] with more
//! functionality. For example, an authentication package could implement a `user` method on
//! `Request`, to access the authenticated user provided by middleware.
//!
//! Extension traits are written by defining a trait + trait impl for the struct that's being
//! extended:
//!
//! ```no_run
//! # use tide::Request;
//! #
//! pub trait RequestExt {
//!     fn bark(&self) -> String;
//! }
//!
//! impl<State> RequestExt for Request<State> {
//!     fn bark(&self) -> String {
//!         "woof".to_string()
//!     }
//! }
//! ```
//!
//! Tide apps will then have access to the `bark` method on `Request`:
//!
//! ```no_run
//! # use tide::Request;
//! #
//! # pub trait RequestExt {
//! #     fn bark(&self) -> String;
//! # }
//! #
//! # impl<State> RequestExt for Request<State> {
//! #     fn bark(&self) -> String {
//! #         "woof".to_string()
//! #     }
//! # }
//! #
//! #[async_std::main]
//! async fn main() -> Result<(), std::io::Error> {
//!     let mut app = tide::new();
//!     app.at("/").get(|req: Request<()>| async move { Ok(req.bark()) });
//!     app.listen("127.0.0.1:8080").await
//! }
//! ```
//!
//! # API Stability
//!
//! It's still early in Tide's development cycle. While the general shape of Tide might have
//! roughly established, the exact traits and function parameters may change between versions. In
//! practice this means that building your core business on Tide is probably not a wise idea...
//! yet.
//!
//! However we *are* committed to closely following semver, and documenting any and all breaking
//! changes we make. Also as time goes on you may find that fewer and fewer changes occur, until we
//! eventually remove this notice entirely. The goal of Tide is to build a premier HTTP experience
//! for Async Rust. We have a long journey ahead of us. But we're excited you're here with us!

#![cfg_attr(feature = "docs", feature(doc_cfg))]
// #![warn(missing_docs)]
#![warn(missing_debug_implementations, rust_2018_idioms)]
#![doc(test(attr(deny(rust_2018_idioms, warnings))))]
#![doc(test(attr(allow(unused_extern_crates, unused_variables))))]
#![doc(html_favicon_url = "https://yoshuawuyts.com/assets/http-rs/favicon.ico")]
#![doc(html_logo_url = "https://yoshuawuyts.com/assets/http-rs/logo-rounded.png")]

mod cookies;
mod endpoint;
mod fs;
mod middleware;
mod redirect;
mod request;
mod response;
mod response_builder;
mod route;

#[cfg(not(feature = "__internal__bench"))]
mod router;
#[cfg(feature = "__internal__bench")]
pub mod router;
mod server;

pub mod convert;
pub mod listener;
pub mod log;
pub mod prelude;
pub mod security;
pub mod sse;
pub mod utils;

#[cfg(feature = "sessions")]
pub mod sessions;

pub use endpoint::Endpoint;
pub use middleware::{Middleware, Next};
pub use redirect::Redirect;
pub use request::{ParamError, Request};
pub use response::Response;
pub use response_builder::ResponseBuilder;
pub use route::Route;
pub use server::Server;

#[doc(inline)]
pub use http_types::{self as http, Body, Error, Status, StatusCode};

/// Create a new Tide server.
///
/// # Examples
///
/// ```no_run
/// # use async_std::task::block_on;
/// # fn main() -> Result<(), std::io::Error> { block_on(async {
/// #
/// let mut app = tide::new();
/// app.at("/").get(|_| async { Ok("Hello, world!") });
/// app.listen("127.0.0.1:8080").await?;
/// #
/// # Ok(()) }) }
/// ```
#[must_use]
pub fn new() -> server::Server<()> {
    Server::new()
}

/// Create a new Tide server with shared application scoped state.
///
/// Application scoped state is useful for storing items
///
/// # Examples
///
/// ```no_run
/// # use async_std::task::block_on;
/// # fn main() -> Result<(), std::io::Error> { block_on(async {
/// #
/// use tide::Request;
///
/// /// The shared application state.
/// #[derive(Clone)]
/// struct State {
///     name: String,
/// }
///
/// // Define a new instance of the state.
/// let state = State {
///     name: "Nori".to_string()
/// };
///
/// // Initialize the application with state.
/// let mut app = tide::with_state(state);
/// app.at("/").get(|req: Request<State>| async move {
///     Ok(format!("Hello, {}!", &req.state().name))
/// });
/// app.listen("127.0.0.1:8080").await?;
/// #
/// # Ok(()) }) }
/// ```
pub fn with_state<State>(state: State) -> server::Server<State>
where
    State: Clone + Send + Sync + 'static,
{
    Server::with_state(state)
}

/// A specialized Result type for Tide.
pub type Result<T = Response> = std::result::Result<T, Error>;