15351 lines
330 KiB
Markdown
15351 lines
330 KiB
Markdown
# Crate Documentation
|
|
|
|
**Version:** 0.8.7
|
|
|
|
**Format Version:** 56
|
|
|
|
# Module `axum`
|
|
|
|
axum is a web application framework that focuses on ergonomics and modularity.
|
|
|
|
# High-level features
|
|
|
|
- Route requests to handlers with a macro-free API.
|
|
- Declaratively parse requests using extractors.
|
|
- Simple and predictable error handling model.
|
|
- Generate responses with minimal boilerplate.
|
|
- Take full advantage of the [`tower`] and [`tower-http`] ecosystem of
|
|
middleware, services, and utilities.
|
|
|
|
In particular, the last point is what sets `axum` apart from other frameworks.
|
|
`axum` doesn't have its own middleware system but instead uses
|
|
[`tower::Service`]. This means `axum` gets timeouts, tracing, compression,
|
|
authorization, and more, for free. It also enables you to share middleware with
|
|
applications written using [`hyper`] or [`tonic`].
|
|
|
|
# Compatibility
|
|
|
|
axum is designed to work with [tokio] and [hyper]. Runtime and
|
|
transport layer independence is not a goal, at least for the time being.
|
|
|
|
# Example
|
|
|
|
The "Hello, World!" of axum is:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
routing::get,
|
|
Router,
|
|
};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
// build our application with a single route
|
|
let app = Router::new().route("/", get(|| async { "Hello, World!" }));
|
|
|
|
// run our app with hyper, listening globally on port 3000
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
|
axum::serve(listener, app).await.unwrap();
|
|
}
|
|
```
|
|
|
|
Note using `#[tokio::main]` requires you enable tokio's `macros` and `rt-multi-thread` features
|
|
or just `full` to enable all features (`cargo add tokio --features macros,rt-multi-thread`).
|
|
|
|
# Routing
|
|
|
|
[`Router`] is used to set up which paths go to which services:
|
|
|
|
```rust
|
|
use axum::{Router, routing::get};
|
|
|
|
// our router
|
|
let app = Router::new()
|
|
.route("/", get(root))
|
|
.route("/foo", get(get_foo).post(post_foo))
|
|
.route("/foo/bar", get(foo_bar));
|
|
|
|
// which calls one of these handlers
|
|
async fn root() {}
|
|
async fn get_foo() {}
|
|
async fn post_foo() {}
|
|
async fn foo_bar() {}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
See [`Router`] for more details on routing.
|
|
|
|
# Handlers
|
|
|
|
In axum a "handler" is an async function that accepts zero or more
|
|
["extractors"](crate::extract) as arguments and returns something that
|
|
can be converted [into a response](crate::response).
|
|
|
|
Handlers are where your application logic lives and axum applications are built
|
|
by routing between handlers.
|
|
|
|
[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html
|
|
|
|
See [`handler`](crate::handler) for more details on handlers.
|
|
|
|
# Extractors
|
|
|
|
An extractor is a type that implements [`FromRequest`] or [`FromRequestParts`]. Extractors are
|
|
how you pick apart the incoming request to get the parts your handler needs.
|
|
|
|
```rust
|
|
use axum::extract::{Path, Query, Json};
|
|
use std::collections::HashMap;
|
|
|
|
// `Path` gives you the path parameters and deserializes them.
|
|
async fn path(Path(user_id): Path<u32>) {}
|
|
|
|
// `Query` gives you the query parameters and deserializes them.
|
|
async fn query(Query(params): Query<HashMap<String, String>>) {}
|
|
|
|
// Buffer the request body and deserialize it as JSON into a
|
|
// `serde_json::Value`. `Json` supports any type that implements
|
|
// `serde::Deserialize`.
|
|
async fn json(Json(payload): Json<serde_json::Value>) {}
|
|
```
|
|
|
|
See [`extract`](crate::extract) for more details on extractors.
|
|
|
|
# Responses
|
|
|
|
Anything that implements [`IntoResponse`] can be returned from handlers.
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
body::Body,
|
|
routing::get,
|
|
response::Json,
|
|
Router,
|
|
};
|
|
use serde_json::{Value, json};
|
|
|
|
// `&'static str` becomes a `200 OK` with `content-type: text/plain; charset=utf-8`
|
|
async fn plain_text() -> &'static str {
|
|
"foo"
|
|
}
|
|
|
|
// `Json` gives a content-type of `application/json` and works with any type
|
|
// that implements `serde::Serialize`
|
|
async fn json() -> Json<Value> {
|
|
Json(json!({ "data": 42 }))
|
|
}
|
|
|
|
let app = Router::new()
|
|
.route("/plain_text", get(plain_text))
|
|
.route("/json", get(json));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
See [`response`](crate::response) for more details on building responses.
|
|
|
|
# Error handling
|
|
|
|
axum aims to have a simple and predictable error handling model. That means
|
|
it is simple to convert errors into responses and you are guaranteed that
|
|
all errors are handled.
|
|
|
|
See [`error_handling`] for more details on axum's
|
|
error handling model and how to handle errors gracefully.
|
|
|
|
# Middleware
|
|
|
|
There are several different ways to write middleware for axum. See
|
|
[`middleware`] for more details.
|
|
|
|
# Sharing state with handlers
|
|
|
|
It is common to share some state between handlers. For example, a
|
|
pool of database connections or clients to other services may need to
|
|
be shared.
|
|
|
|
The four most common ways of doing that are:
|
|
|
|
- Using the [`State`] extractor
|
|
- Using request extensions
|
|
- Using closure captures
|
|
- Using task-local variables
|
|
|
|
## Using the [`State`] extractor
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::State,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use std::sync::Arc;
|
|
|
|
struct AppState {
|
|
// ...
|
|
}
|
|
|
|
let shared_state = Arc::new(AppState { /* ... */ });
|
|
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.with_state(shared_state);
|
|
|
|
async fn handler(
|
|
State(state): State<Arc<AppState>>,
|
|
) {
|
|
// ...
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
You should prefer using [`State`] if possible since it's more type safe. The downside is that
|
|
it's less dynamic than task-local variables and request extensions.
|
|
|
|
See [`State`] for more details about accessing state.
|
|
|
|
## Using request extensions
|
|
|
|
Another way to share state with handlers is using [`Extension`] as
|
|
layer and extractor:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Extension,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use std::sync::Arc;
|
|
|
|
struct AppState {
|
|
// ...
|
|
}
|
|
|
|
let shared_state = Arc::new(AppState { /* ... */ });
|
|
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.layer(Extension(shared_state));
|
|
|
|
async fn handler(
|
|
Extension(state): Extension<Arc<AppState>>,
|
|
) {
|
|
// ...
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
The downside to this approach is that you'll get runtime errors
|
|
(specifically a `500 Internal Server Error` response) if you try and extract
|
|
an extension that doesn't exist, perhaps because you forgot to add the
|
|
middleware or because you're extracting the wrong type.
|
|
|
|
## Using closure captures
|
|
|
|
State can also be passed directly to handlers using closure captures:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
Json,
|
|
extract::{Extension, Path},
|
|
routing::{get, post},
|
|
Router,
|
|
};
|
|
use std::sync::Arc;
|
|
use serde::Deserialize;
|
|
|
|
struct AppState {
|
|
// ...
|
|
}
|
|
|
|
let shared_state = Arc::new(AppState { /* ... */ });
|
|
|
|
let app = Router::new()
|
|
.route(
|
|
"/users",
|
|
post({
|
|
let shared_state = Arc::clone(&shared_state);
|
|
move |body| create_user(body, shared_state)
|
|
}),
|
|
)
|
|
.route(
|
|
"/users/{id}",
|
|
get({
|
|
let shared_state = Arc::clone(&shared_state);
|
|
move |path| get_user(path, shared_state)
|
|
}),
|
|
);
|
|
|
|
async fn get_user(Path(user_id): Path<String>, state: Arc<AppState>) {
|
|
// ...
|
|
}
|
|
|
|
async fn create_user(Json(payload): Json<CreateUserPayload>, state: Arc<AppState>) {
|
|
// ...
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
struct CreateUserPayload {
|
|
// ...
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
The downside to this approach is that it's the most verbose approach.
|
|
|
|
## Using task-local variables
|
|
|
|
This also allows to share state with `IntoResponse` implementations:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Request,
|
|
http::{header, StatusCode},
|
|
middleware::{self, Next},
|
|
response::{IntoResponse, Response},
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use tokio::task_local;
|
|
|
|
#[derive(Clone)]
|
|
struct CurrentUser {
|
|
name: String,
|
|
}
|
|
task_local! {
|
|
pub static USER: CurrentUser;
|
|
}
|
|
|
|
async fn auth(req: Request, next: Next) -> Result<Response, StatusCode> {
|
|
let auth_header = req
|
|
.headers()
|
|
.get(header::AUTHORIZATION)
|
|
.and_then(|header| header.to_str().ok())
|
|
.ok_or(StatusCode::UNAUTHORIZED)?;
|
|
if let Some(current_user) = authorize_current_user(auth_header).await {
|
|
// State is setup here in the middleware
|
|
Ok(USER.scope(current_user, next.run(req)).await)
|
|
} else {
|
|
Err(StatusCode::UNAUTHORIZED)
|
|
}
|
|
}
|
|
async fn authorize_current_user(auth_token: &str) -> Option<CurrentUser> {
|
|
Some(CurrentUser {
|
|
name: auth_token.to_string(),
|
|
})
|
|
}
|
|
|
|
struct UserResponse;
|
|
|
|
impl IntoResponse for UserResponse {
|
|
fn into_response(self) -> Response {
|
|
// State is accessed here in the IntoResponse implementation
|
|
let current_user = USER.with(|u| u.clone());
|
|
(StatusCode::OK, current_user.name).into_response()
|
|
}
|
|
}
|
|
|
|
async fn handler() -> UserResponse {
|
|
UserResponse
|
|
}
|
|
|
|
let app: Router = Router::new()
|
|
.route("/", get(handler))
|
|
.route_layer(middleware::from_fn(auth));
|
|
```
|
|
|
|
The main downside to this approach is that it only works when the async executor being used
|
|
has the concept of task-local variables. The example above uses
|
|
[tokio's `task_local` macro](https://docs.rs/tokio/1/tokio/macro.task_local.html).
|
|
smol does not yet offer equivalent functionality at the time of writing (see
|
|
[this GitHub issue](https://github.com/smol-rs/async-executor/issues/139)).
|
|
|
|
# Building integrations for axum
|
|
|
|
Libraries authors that want to provide [`FromRequest`], [`FromRequestParts`], or
|
|
[`IntoResponse`] implementations should depend on the [`axum-core`] crate, instead of `axum` if
|
|
possible. [`axum-core`] contains core types and traits and is less likely to receive breaking
|
|
changes.
|
|
|
|
# Required dependencies
|
|
|
|
To use axum there are a few dependencies you have to pull in as well:
|
|
|
|
```toml
|
|
[dependencies]
|
|
axum = "<latest-version>"
|
|
tokio = { version = "<latest-version>", features = ["full"] }
|
|
tower = "<latest-version>"
|
|
```
|
|
|
|
The `"full"` feature for tokio isn't necessary but it's the easiest way to get started.
|
|
|
|
Tower isn't strictly necessary either but helpful for testing. See the
|
|
testing example in the repo to learn more about testing axum apps.
|
|
|
|
# Examples
|
|
|
|
The axum repo contains [a number of examples][examples] that show how to put all the
|
|
pieces together.
|
|
|
|
# Feature flags
|
|
|
|
axum uses a set of [feature flags] to reduce the amount of compiled and
|
|
optional dependencies.
|
|
|
|
The following optional features are available:
|
|
|
|
Name | Description | Default?
|
|
---|---|---
|
|
`http1` | Enables hyper's `http1` feature | <span role="img" aria-label="Default feature">✔</span>
|
|
`http2` | Enables hyper's `http2` feature |
|
|
`json` | Enables the [`Json`] type and some similar convenience functionality | <span role="img" aria-label="Default feature">✔</span>
|
|
`macros` | Enables optional utility macros |
|
|
`matched-path` | Enables capturing of every request's router path and the [`MatchedPath`] extractor | <span role="img" aria-label="Default feature">✔</span>
|
|
`multipart` | Enables parsing `multipart/form-data` requests with [`Multipart`] |
|
|
`original-uri` | Enables capturing of every request's original URI and the [`OriginalUri`] extractor | <span role="img" aria-label="Default feature">✔</span>
|
|
`tokio` | Enables `tokio` as a dependency and `axum::serve`, `SSE` and `extract::connect_info` types. | <span role="img" aria-label="Default feature">✔</span>
|
|
`tower-log` | Enables `tower`'s `log` feature | <span role="img" aria-label="Default feature">✔</span>
|
|
`tracing` | Log rejections from built-in extractors | <span role="img" aria-label="Default feature">✔</span>
|
|
`ws` | Enables WebSockets support via [`extract::ws`] |
|
|
`form` | Enables the `Form` extractor | <span role="img" aria-label="Default feature">✔</span>
|
|
`query` | Enables the `Query` extractor | <span role="img" aria-label="Default feature">✔</span>
|
|
|
|
[`MatchedPath`]: crate::extract::MatchedPath
|
|
[`Multipart`]: crate::extract::Multipart
|
|
[`OriginalUri`]: crate::extract::OriginalUri
|
|
[`tower`]: https://crates.io/crates/tower
|
|
[`tower-http`]: https://crates.io/crates/tower-http
|
|
[`tokio`]: http://crates.io/crates/tokio
|
|
[`hyper`]: http://crates.io/crates/hyper
|
|
[`tonic`]: http://crates.io/crates/tonic
|
|
[feature flags]: https://doc.rust-lang.org/cargo/reference/features.html#the-features-section
|
|
[`IntoResponse`]: crate::response::IntoResponse
|
|
[`Timeout`]: tower::timeout::Timeout
|
|
[examples]: https://github.com/tokio-rs/axum/tree/main/examples
|
|
[`Router::merge`]: crate::routing::Router::merge
|
|
[`Service`]: tower::Service
|
|
[`Service::poll_ready`]: tower::Service::poll_ready
|
|
[`Service`'s]: tower::Service
|
|
[`tower::Service`]: tower::Service
|
|
[tower-guides]: https://github.com/tower-rs/tower/tree/master/guides
|
|
[`Uuid`]: https://docs.rs/uuid/latest/uuid/
|
|
[`FromRequest`]: crate::extract::FromRequest
|
|
[`FromRequestParts`]: crate::extract::FromRequestParts
|
|
[`HeaderMap`]: http::header::HeaderMap
|
|
[`Request`]: http::Request
|
|
[customize-extractor-error]: https://github.com/tokio-rs/axum/blob/main/examples/customize-extractor-error/src/main.rs
|
|
[axum-macros]: https://docs.rs/axum-macros
|
|
[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html
|
|
[`Handler`]: crate::handler::Handler
|
|
[`Infallible`]: std::convert::Infallible
|
|
[load shed]: tower::load_shed
|
|
[`axum-core`]: http://crates.io/crates/axum-core
|
|
[`State`]: crate::extract::State
|
|
|
|
## Modules
|
|
|
|
## Module `body`
|
|
|
|
HTTP body utilities.
|
|
|
|
```rust
|
|
pub mod body { /* ... */ }
|
|
```
|
|
|
|
### Functions
|
|
|
|
#### Function `to_bytes`
|
|
|
|
Converts [`Body`] into [`Bytes`] and limits the maximum size of the body.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::body::{to_bytes, Body};
|
|
|
|
# async fn foo() -> Result<(), axum_core::Error> {
|
|
let body = Body::from(vec![1, 2, 3]);
|
|
// Use `usize::MAX` if you don't care about the maximum size.
|
|
let bytes = to_bytes(body, usize::MAX).await?;
|
|
assert_eq!(&bytes[..], &[1, 2, 3]);
|
|
# Ok(())
|
|
# }
|
|
```
|
|
|
|
You can detect if the limit was hit by checking the source of the error:
|
|
|
|
```rust
|
|
use axum::body::{to_bytes, Body};
|
|
use http_body_util::LengthLimitError;
|
|
|
|
# #[tokio::main]
|
|
# async fn main() {
|
|
let body = Body::from(vec![1, 2, 3]);
|
|
match to_bytes(body, 1).await {
|
|
Ok(_bytes) => panic!("should have hit the limit"),
|
|
Err(err) => {
|
|
let source = std::error::Error::source(&err).unwrap();
|
|
assert!(source.is::<LengthLimitError>());
|
|
}
|
|
}
|
|
# }
|
|
```
|
|
|
|
```rust
|
|
pub async fn to_bytes(body: Body, limit: usize) -> Result<Bytes, axum_core::Error> { /* ... */ }
|
|
```
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `Body`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use http_body::Body as HttpBody;
|
|
```
|
|
|
|
#### Re-export `Bytes`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use bytes::Bytes;
|
|
```
|
|
|
|
#### Re-export `Body`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::body::Body;
|
|
```
|
|
|
|
#### Re-export `BodyDataStream`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::body::BodyDataStream;
|
|
```
|
|
|
|
## Module `error_handling`
|
|
|
|
Error handling model and utilities
|
|
|
|
# axum's error handling model
|
|
|
|
axum is based on [`tower::Service`] which bundles errors through its associated
|
|
`Error` type. If you have a [`Service`] that produces an error and that error
|
|
makes it all the way up to hyper, the connection will be terminated _without_
|
|
sending a response. This is generally not desirable so axum makes sure you
|
|
always produce a response by relying on the type system.
|
|
|
|
axum does this by requiring all services have [`Infallible`] as their error
|
|
type. `Infallible` is the error type for errors that can never happen.
|
|
|
|
This means if you define a handler like:
|
|
|
|
```rust
|
|
use axum::http::StatusCode;
|
|
|
|
async fn handler() -> Result<String, StatusCode> {
|
|
# todo!()
|
|
// ...
|
|
}
|
|
```
|
|
|
|
While it looks like it might fail with a `StatusCode` this actually isn't an
|
|
"error". If this handler returns `Err(some_status_code)` that will still be
|
|
converted into a [`Response`] and sent back to the client. This is done
|
|
through `StatusCode`'s [`IntoResponse`] implementation.
|
|
|
|
It doesn't matter whether you return `Err(StatusCode::NOT_FOUND)` or
|
|
`Err(StatusCode::INTERNAL_SERVER_ERROR)`. These are not considered errors in
|
|
axum.
|
|
|
|
Instead of a direct `StatusCode`, it makes sense to use intermediate error type
|
|
that can ultimately be converted to `Response`. This allows using `?` operator
|
|
in handlers. See those examples:
|
|
|
|
* [`anyhow-error-response`][anyhow] for generic boxed errors
|
|
* [`error-handling`][error-handling] for application-specific detailed errors
|
|
|
|
[anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs
|
|
[error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs
|
|
|
|
This also applies to extractors. If an extractor doesn't match the request the
|
|
request will be rejected and a response will be returned without calling your
|
|
handler. See [`extract`](crate::extract) to learn more about handling extractor
|
|
failures.
|
|
|
|
# Routing to fallible services
|
|
|
|
You generally don't have to think about errors if you're only using async
|
|
functions as handlers. However if you're embedding general `Service`s or
|
|
applying middleware, which might produce errors you have to tell axum how to
|
|
convert those errors into responses.
|
|
|
|
```rust
|
|
use axum::{
|
|
Router,
|
|
body::Body,
|
|
http::{Request, Response, StatusCode},
|
|
error_handling::HandleError,
|
|
};
|
|
|
|
async fn thing_that_might_fail() -> Result<(), anyhow::Error> {
|
|
# Ok(())
|
|
// ...
|
|
}
|
|
|
|
// this service might fail with `anyhow::Error`
|
|
let some_fallible_service = tower::service_fn(|_req| async {
|
|
thing_that_might_fail().await?;
|
|
Ok::<_, anyhow::Error>(Response::new(Body::empty()))
|
|
});
|
|
|
|
let app = Router::new().route_service(
|
|
"/",
|
|
// we cannot route to `some_fallible_service` directly since it might fail.
|
|
// we have to use `handle_error` which converts its errors into responses
|
|
// and changes its error type from `anyhow::Error` to `Infallible`.
|
|
HandleError::new(some_fallible_service, handle_anyhow_error),
|
|
);
|
|
|
|
// handle errors by converting them into something that implements
|
|
// `IntoResponse`
|
|
async fn handle_anyhow_error(err: anyhow::Error) -> (StatusCode, String) {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Something went wrong: {err}"),
|
|
)
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Applying fallible middleware
|
|
|
|
Similarly axum requires you to handle errors from middleware. That is done with
|
|
[`HandleErrorLayer`]:
|
|
|
|
```rust
|
|
use axum::{
|
|
Router,
|
|
BoxError,
|
|
routing::get,
|
|
http::StatusCode,
|
|
error_handling::HandleErrorLayer,
|
|
};
|
|
use std::time::Duration;
|
|
use tower::ServiceBuilder;
|
|
|
|
let app = Router::new()
|
|
.route("/", get(|| async {}))
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
// `timeout` will produce an error if the handler takes
|
|
// too long so we must handle those
|
|
.layer(HandleErrorLayer::new(handle_timeout_error))
|
|
.timeout(Duration::from_secs(30))
|
|
);
|
|
|
|
async fn handle_timeout_error(err: BoxError) -> (StatusCode, String) {
|
|
if err.is::<tower::timeout::error::Elapsed>() {
|
|
(
|
|
StatusCode::REQUEST_TIMEOUT,
|
|
"Request took too long".to_string(),
|
|
)
|
|
} else {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Unhandled internal error: {err}"),
|
|
)
|
|
}
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Running extractors for error handling
|
|
|
|
`HandleErrorLayer` also supports running extractors:
|
|
|
|
```rust
|
|
use axum::{
|
|
Router,
|
|
BoxError,
|
|
routing::get,
|
|
http::{StatusCode, Method, Uri},
|
|
error_handling::HandleErrorLayer,
|
|
};
|
|
use std::time::Duration;
|
|
use tower::ServiceBuilder;
|
|
|
|
let app = Router::new()
|
|
.route("/", get(|| async {}))
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
// `timeout` will produce an error if the handler takes
|
|
// too long so we must handle those
|
|
.layer(HandleErrorLayer::new(handle_timeout_error))
|
|
.timeout(Duration::from_secs(30))
|
|
);
|
|
|
|
async fn handle_timeout_error(
|
|
// `Method` and `Uri` are extractors so they can be used here
|
|
method: Method,
|
|
uri: Uri,
|
|
// the last argument must be the error itself
|
|
err: BoxError,
|
|
) -> (StatusCode, String) {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("`{method} {uri}` failed with {err}"),
|
|
)
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
[`tower::Service`]: `tower::Service`
|
|
[`Infallible`]: std::convert::Infallible
|
|
[`Response`]: crate::response::Response
|
|
[`IntoResponse`]: crate::response::IntoResponse
|
|
|
|
```rust
|
|
pub mod error_handling { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `future`
|
|
|
|
Future types.
|
|
|
|
```rust
|
|
pub mod future { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `HandleErrorFuture`
|
|
|
|
Response future for [`HandleError`].
|
|
|
|
```rust
|
|
pub struct HandleErrorFuture {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Future**
|
|
- ```rust
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<<Self as >::Output> { /* ... */ }
|
|
```
|
|
|
|
- **FutureExt**
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoFuture**
|
|
- ```rust
|
|
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryFuture**
|
|
- ```rust
|
|
fn try_poll(self: Pin<&mut F>, cx: &mut Context<''_>) -> Poll<<F as Future>::Output> { /* ... */ }
|
|
```
|
|
|
|
- **TryFutureExt**
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Types
|
|
|
|
#### Struct `HandleErrorLayer`
|
|
|
|
[`Layer`] that applies [`HandleError`] which is a [`Service`] adapter
|
|
that handles errors by converting them into responses.
|
|
|
|
See [module docs](self) for more details on axum's error handling model.
|
|
|
|
```rust
|
|
pub struct HandleErrorLayer<F, T> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn new(f: F) -> Self { /* ... */ }
|
|
```
|
|
Create a new `HandleErrorLayer`.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **Layer**
|
|
- ```rust
|
|
fn layer(self: &Self, inner: S) -> <Self as >::Service { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `HandleError`
|
|
|
|
A [`Service`] adapter that handles errors by converting them into responses.
|
|
|
|
See [module docs](self) for more details on axum's error handling model.
|
|
|
|
```rust
|
|
pub struct HandleError<S, F, T> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn new(inner: S, f: F) -> Self { /* ... */ }
|
|
```
|
|
Create a new `HandleError`.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **MakeService**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll<Result<(), <M as MakeService<Target, Request>>::MakeError>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn make_service(self: &mut Self, target: Target) -> <M as MakeService<Target, Request>>::Future { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<S> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<S, C> { /* ... */ }
|
|
```
|
|
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
## Module `extract`
|
|
|
|
Types and traits for extracting data from requests.
|
|
|
|
# Intro
|
|
|
|
A handler function is an async function that takes any number of
|
|
"extractors" as arguments. An extractor is a type that implements
|
|
[`FromRequest`] or [`FromRequestParts`].
|
|
|
|
For example, [`Json`] is an extractor that consumes the request body and
|
|
deserializes it as JSON into some target type:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Json,
|
|
routing::post,
|
|
handler::Handler,
|
|
Router,
|
|
};
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Deserialize)]
|
|
struct CreateUser {
|
|
email: String,
|
|
password: String,
|
|
}
|
|
|
|
async fn create_user(Json(payload): Json<CreateUser>) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new().route("/users", post(create_user));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Common extractors
|
|
|
|
Some commonly used extractors are:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::{Request, Json, Path, Extension, Query},
|
|
routing::post,
|
|
http::header::HeaderMap,
|
|
body::{Bytes, Body},
|
|
Router,
|
|
};
|
|
use serde_json::Value;
|
|
use std::collections::HashMap;
|
|
|
|
// `Path` gives you the path parameters and deserializes them. See its docs for
|
|
// more details
|
|
async fn path(Path(user_id): Path<u32>) {}
|
|
|
|
// `Query` gives you the query parameters and deserializes them.
|
|
async fn query(Query(params): Query<HashMap<String, String>>) {}
|
|
|
|
// `HeaderMap` gives you all the headers
|
|
async fn headers(headers: HeaderMap) {}
|
|
|
|
// `String` consumes the request body and ensures it is valid utf-8
|
|
async fn string(body: String) {}
|
|
|
|
// `Bytes` gives you the raw request body
|
|
async fn bytes(body: Bytes) {}
|
|
|
|
// We've already seen `Json` for parsing the request body as json
|
|
async fn json(Json(payload): Json<Value>) {}
|
|
|
|
// `Request` gives you the whole request for maximum control
|
|
async fn request(request: Request) {}
|
|
|
|
// `Extension` extracts data from "request extensions"
|
|
// This is commonly used to share state with handlers
|
|
async fn extension(Extension(state): Extension<State>) {}
|
|
|
|
#[derive(Clone)]
|
|
struct State { /* ... */ }
|
|
|
|
let app = Router::new()
|
|
.route("/path/{user_id}", post(path))
|
|
.route("/query", post(query))
|
|
.route("/string", post(string))
|
|
.route("/bytes", post(bytes))
|
|
.route("/json", post(json))
|
|
.route("/request", post(request))
|
|
.route("/extension", post(extension));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Applying multiple extractors
|
|
|
|
You can also apply multiple extractors:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::{Path, Query},
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use uuid::Uuid;
|
|
use serde::Deserialize;
|
|
|
|
let app = Router::new().route("/users/{id}/things", get(get_user_things));
|
|
|
|
#[derive(Deserialize)]
|
|
struct Pagination {
|
|
page: usize,
|
|
per_page: usize,
|
|
}
|
|
|
|
async fn get_user_things(
|
|
Path(user_id): Path<Uuid>,
|
|
Query(pagination): Query<Pagination>,
|
|
) {
|
|
// ...
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# The order of extractors
|
|
|
|
Extractors always run in the order of the function parameters that is from
|
|
left to right.
|
|
|
|
The request body is an asynchronous stream that can only be consumed once.
|
|
Therefore you can only have one extractor that consumes the request body. axum
|
|
enforces this by requiring such extractors to be the _last_ argument your
|
|
handler takes.
|
|
|
|
For example
|
|
|
|
```rust
|
|
use axum::{extract::State, http::{Method, HeaderMap}};
|
|
#
|
|
# #[derive(Clone)]
|
|
# struct AppState {
|
|
# }
|
|
|
|
async fn handler(
|
|
// `Method` and `HeaderMap` don't consume the request body so they can
|
|
// put anywhere in the argument list (but before `body`)
|
|
method: Method,
|
|
headers: HeaderMap,
|
|
// `State` is also an extractor so it needs to be before `body`
|
|
State(state): State<AppState>,
|
|
// `String` consumes the request body and thus must be the last extractor
|
|
body: String,
|
|
) {
|
|
// ...
|
|
}
|
|
#
|
|
# let _: axum::routing::MethodRouter<AppState> = axum::routing::get(handler);
|
|
```
|
|
|
|
We get a compile error if `String` isn't the last extractor:
|
|
|
|
```rust,compile_fail
|
|
use axum::http::Method;
|
|
|
|
async fn handler(
|
|
// this doesn't work since `String` must be the last argument
|
|
body: String,
|
|
method: Method,
|
|
) {
|
|
// ...
|
|
}
|
|
#
|
|
# let _: axum::routing::MethodRouter = axum::routing::get(handler);
|
|
```
|
|
|
|
This also means you cannot consume the request body twice:
|
|
|
|
```rust,compile_fail
|
|
use axum::Json;
|
|
use serde::Deserialize;
|
|
|
|
#[derive(Deserialize)]
|
|
struct Payload {}
|
|
|
|
async fn handler(
|
|
// `String` and `Json` both consume the request body
|
|
// so they cannot both be used
|
|
string_body: String,
|
|
json_body: Json<Payload>,
|
|
) {
|
|
// ...
|
|
}
|
|
#
|
|
# let _: axum::routing::MethodRouter = axum::routing::get(handler);
|
|
```
|
|
|
|
axum enforces this by requiring the last extractor implements [`FromRequest`]
|
|
and all others implement [`FromRequestParts`].
|
|
|
|
# Handling extractor rejections
|
|
|
|
If you want to handle the case of an extractor failing within a specific
|
|
handler, you can wrap it in `Result`, with the error being the rejection type
|
|
of the extractor:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::{Json, rejection::JsonRejection},
|
|
routing::post,
|
|
Router,
|
|
};
|
|
use serde_json::Value;
|
|
|
|
async fn create_user(payload: Result<Json<Value>, JsonRejection>) {
|
|
match payload {
|
|
Ok(payload) => {
|
|
// We got a valid JSON payload
|
|
}
|
|
Err(JsonRejection::MissingJsonContentType(_)) => {
|
|
// Request didn't have `Content-Type: application/json`
|
|
// header
|
|
}
|
|
Err(JsonRejection::JsonDataError(_)) => {
|
|
// Couldn't deserialize the body into the target type
|
|
}
|
|
Err(JsonRejection::JsonSyntaxError(_)) => {
|
|
// Syntax error in the body
|
|
}
|
|
Err(JsonRejection::BytesRejection(_)) => {
|
|
// Failed to extract the request body
|
|
}
|
|
Err(_) => {
|
|
// `JsonRejection` is marked `#[non_exhaustive]` so match must
|
|
// include a catch-all case.
|
|
}
|
|
}
|
|
}
|
|
|
|
let app = Router::new().route("/users", post(create_user));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Optional extractors
|
|
|
|
Some extractors implement [`OptionalFromRequestParts`] in addition to
|
|
[`FromRequestParts`], or [`OptionalFromRequest`] in addition to [`FromRequest`].
|
|
|
|
These extractors can be used inside of `Option`. It depends on the particular
|
|
`OptionalFromRequestParts` or `OptionalFromRequest` implementation what this
|
|
does: For example for `TypedHeader` from axum-extra, you get `None` if the
|
|
header you're trying to extract is not part of the request, but if the header
|
|
is present and fails to parse, the request is rejected.
|
|
|
|
```rust,no_run
|
|
use axum::{routing::post, Router};
|
|
use axum_extra::{headers::UserAgent, TypedHeader};
|
|
use serde_json::Value;
|
|
|
|
async fn foo(user_agent: Option<TypedHeader<UserAgent>>) {
|
|
if let Some(TypedHeader(user_agent)) = user_agent {
|
|
// The client sent a user agent
|
|
} else {
|
|
// No user agent header
|
|
}
|
|
}
|
|
|
|
let app = Router::new().route("/foo", post(foo));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Customizing extractor responses
|
|
|
|
If an extractor fails it will return a response with the error and your
|
|
handler will not be called. To customize the error response you have two
|
|
options:
|
|
|
|
1. Use `Result<T, T::Rejection>` as your extractor like shown in
|
|
["Handling extractor rejections"](#handling-extractor-rejections).
|
|
This works well if you're only using the extractor in a single handler.
|
|
2. Create your own extractor that in its [`FromRequest`] implementation calls
|
|
one of axum's built in extractors but returns a different response for
|
|
rejections. See the [customize-extractor-error] example for more details.
|
|
|
|
# Accessing inner errors
|
|
|
|
axum's built-in extractors don't directly expose the inner error. This gives us
|
|
more flexibility and allows us to change internal implementations without
|
|
breaking the public API.
|
|
|
|
For example that means while [`Json`] is implemented using [`serde_json`] it
|
|
doesn't directly expose the [`serde_json::Error`] that's contained in
|
|
[`JsonRejection::JsonDataError`]. However it is still possible to access via
|
|
methods from [`std::error::Error`]:
|
|
|
|
```rust
|
|
use std::error::Error;
|
|
use axum::{
|
|
extract::{Json, rejection::JsonRejection},
|
|
response::IntoResponse,
|
|
http::StatusCode,
|
|
};
|
|
use serde_json::{json, Value};
|
|
|
|
async fn handler(
|
|
result: Result<Json<Value>, JsonRejection>,
|
|
) -> Result<Json<Value>, (StatusCode, String)> {
|
|
match result {
|
|
// if the client sent valid JSON then we're good
|
|
Ok(Json(payload)) => Ok(Json(json!({ "payload": payload }))),
|
|
|
|
Err(err) => match err {
|
|
JsonRejection::JsonDataError(err) => {
|
|
Err(serde_json_error_response(err))
|
|
}
|
|
JsonRejection::JsonSyntaxError(err) => {
|
|
Err(serde_json_error_response(err))
|
|
}
|
|
// handle other rejections from the `Json` extractor
|
|
JsonRejection::MissingJsonContentType(_) => Err((
|
|
StatusCode::BAD_REQUEST,
|
|
"Missing `Content-Type: application/json` header".to_string(),
|
|
)),
|
|
JsonRejection::BytesRejection(_) => Err((
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
"Failed to buffer request body".to_string(),
|
|
)),
|
|
// we must provide a catch-all case since `JsonRejection` is marked
|
|
// `#[non_exhaustive]`
|
|
_ => Err((
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
"Unknown error".to_string(),
|
|
)),
|
|
},
|
|
}
|
|
}
|
|
|
|
// attempt to extract the inner `serde_path_to_error::Error<serde_json::Error>`,
|
|
// if that succeeds we can provide a more specific error.
|
|
//
|
|
// `Json` uses `serde_path_to_error` so the error will be wrapped in `serde_path_to_error::Error`.
|
|
fn serde_json_error_response<E>(err: E) -> (StatusCode, String)
|
|
where
|
|
E: Error + 'static,
|
|
{
|
|
if let Some(err) = find_error_source::<serde_path_to_error::Error<serde_json::Error>>(&err) {
|
|
let serde_json_err = err.inner();
|
|
(
|
|
StatusCode::BAD_REQUEST,
|
|
format!(
|
|
"Invalid JSON at line {} column {}",
|
|
serde_json_err.line(),
|
|
serde_json_err.column()
|
|
),
|
|
)
|
|
} else {
|
|
(StatusCode::BAD_REQUEST, "Unknown error".to_string())
|
|
}
|
|
}
|
|
|
|
// attempt to downcast `err` into a `T` and if that fails recursively try and
|
|
// downcast `err`'s source
|
|
fn find_error_source<'a, T>(err: &'a (dyn Error + 'static)) -> Option<&'a T>
|
|
where
|
|
T: Error + 'static,
|
|
{
|
|
if let Some(err) = err.downcast_ref::<T>() {
|
|
Some(err)
|
|
} else if let Some(source) = err.source() {
|
|
find_error_source(source)
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
#
|
|
# #[tokio::main]
|
|
# async fn main() {
|
|
# use axum::extract::FromRequest;
|
|
#
|
|
# let req = axum::http::Request::builder()
|
|
# .header("content-type", "application/json")
|
|
# .body(axum::body::Body::from("{"))
|
|
# .unwrap();
|
|
#
|
|
# let err = match Json::<serde_json::Value>::from_request(req, &()).await.unwrap_err() {
|
|
# JsonRejection::JsonSyntaxError(err) => err,
|
|
# _ => panic!(),
|
|
# };
|
|
#
|
|
# let (_, body) = serde_json_error_response(err);
|
|
# assert_eq!(body, "Invalid JSON at line 1 column 1");
|
|
# }
|
|
```
|
|
|
|
Note that while this approach works it might break in the future if axum changes
|
|
its implementation to use a different error type internally. Such changes might
|
|
happen without major breaking versions.
|
|
|
|
# Defining custom extractors
|
|
|
|
You can also define your own extractors by implementing either
|
|
[`FromRequestParts`] or [`FromRequest`].
|
|
|
|
## Implementing `FromRequestParts`
|
|
|
|
Implement `FromRequestParts` if your extractor doesn't need access to the
|
|
request body:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::FromRequestParts,
|
|
routing::get,
|
|
Router,
|
|
http::{
|
|
StatusCode,
|
|
header::{HeaderValue, USER_AGENT},
|
|
request::Parts,
|
|
},
|
|
};
|
|
|
|
struct ExtractUserAgent(HeaderValue);
|
|
|
|
impl<S> FromRequestParts<S> for ExtractUserAgent
|
|
where
|
|
S: Send + Sync,
|
|
{
|
|
type Rejection = (StatusCode, &'static str);
|
|
|
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
|
if let Some(user_agent) = parts.headers.get(USER_AGENT) {
|
|
Ok(ExtractUserAgent(user_agent.clone()))
|
|
} else {
|
|
Err((StatusCode::BAD_REQUEST, "`User-Agent` header is missing"))
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn handler(ExtractUserAgent(user_agent): ExtractUserAgent) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new().route("/foo", get(handler));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
## Implementing `FromRequest`
|
|
|
|
If your extractor needs to consume the request body you must implement [`FromRequest`]
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::{Request, FromRequest},
|
|
response::{Response, IntoResponse},
|
|
body::{Bytes, Body},
|
|
routing::get,
|
|
Router,
|
|
http::{
|
|
StatusCode,
|
|
header::{HeaderValue, USER_AGENT},
|
|
},
|
|
};
|
|
|
|
struct ValidatedBody(Bytes);
|
|
|
|
impl<S> FromRequest<S> for ValidatedBody
|
|
where
|
|
Bytes: FromRequest<S>,
|
|
S: Send + Sync,
|
|
{
|
|
type Rejection = Response;
|
|
|
|
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
|
let body = Bytes::from_request(req, state)
|
|
.await
|
|
.map_err(IntoResponse::into_response)?;
|
|
|
|
// do validation...
|
|
|
|
Ok(Self(body))
|
|
}
|
|
}
|
|
|
|
async fn handler(ValidatedBody(body): ValidatedBody) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new().route("/foo", get(handler));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
## Cannot implement both `FromRequest` and `FromRequestParts`
|
|
|
|
Note that you will make your extractor unusable by implementing both
|
|
`FromRequest` and `FromRequestParts` directly for the same type, unless it is
|
|
wrapping another extractor:
|
|
|
|
```rust,compile_fail
|
|
use axum::{
|
|
Router,
|
|
routing::get,
|
|
extract::{FromRequest, Request, FromRequestParts},
|
|
http::request::Parts,
|
|
body::Body,
|
|
};
|
|
use std::convert::Infallible;
|
|
|
|
// Some extractor that doesn't wrap another extractor
|
|
struct MyExtractor;
|
|
|
|
// `MyExtractor` implements both `FromRequest`
|
|
impl<S> FromRequest<S> for MyExtractor
|
|
where
|
|
S: Send + Sync,
|
|
{
|
|
type Rejection = Infallible;
|
|
|
|
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
|
// ...
|
|
# todo!()
|
|
}
|
|
}
|
|
|
|
// and `FromRequestParts`
|
|
impl<S> FromRequestParts<S> for MyExtractor
|
|
where
|
|
S: Send + Sync,
|
|
{
|
|
type Rejection = Infallible;
|
|
|
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
|
// ...
|
|
# todo!()
|
|
}
|
|
}
|
|
|
|
let app = Router::new().route(
|
|
"/",
|
|
// This fails when we go to actually use `MyExtractor` in a handler function.
|
|
// This is due to a limit in Rust's type system.
|
|
//
|
|
// The workaround is to implement either `FromRequest` or `FromRequestParts`
|
|
// but not both, if your extractor doesn't wrap another extractor.
|
|
//
|
|
// See "Wrapping extractors" for how to wrap other extractors.
|
|
get(|_: MyExtractor| async {}),
|
|
);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Accessing other extractors in `FromRequest` or `FromRequestParts` implementations
|
|
|
|
When defining custom extractors you often need to access another extractor
|
|
in your implementation.
|
|
|
|
```rust
|
|
use axum::{
|
|
extract::{Extension, FromRequestParts},
|
|
http::{StatusCode, HeaderMap, request::Parts},
|
|
response::{IntoResponse, Response},
|
|
routing::get,
|
|
Router,
|
|
};
|
|
|
|
#[derive(Clone)]
|
|
struct State {
|
|
// ...
|
|
}
|
|
|
|
struct AuthenticatedUser {
|
|
// ...
|
|
}
|
|
|
|
impl<S> FromRequestParts<S> for AuthenticatedUser
|
|
where
|
|
S: Send + Sync,
|
|
{
|
|
type Rejection = Response;
|
|
|
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
|
// You can either call them directly...
|
|
let headers = HeaderMap::from_request_parts(parts, state)
|
|
.await
|
|
.map_err(|err| match err {})?;
|
|
|
|
// ... or use `extract` / `extract_with_state` from `RequestExt` / `RequestPartsExt`
|
|
use axum::RequestPartsExt;
|
|
let Extension(state) = parts.extract::<Extension<State>>()
|
|
.await
|
|
.map_err(|err| err.into_response())?;
|
|
|
|
unimplemented!("actually perform the authorization")
|
|
}
|
|
}
|
|
|
|
async fn handler(user: AuthenticatedUser) {
|
|
// ...
|
|
}
|
|
|
|
let state = State { /* ... */ };
|
|
|
|
let app = Router::new().route("/", get(handler)).layer(Extension(state));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Request body limits
|
|
|
|
For security reasons, [`Bytes`] will, by default, not accept bodies larger than
|
|
2MB. This also applies to extractors that uses [`Bytes`] internally such as
|
|
`String`, [`Json`], and [`Form`].
|
|
|
|
For more details, including how to disable this limit, see [`DefaultBodyLimit`].
|
|
|
|
# Wrapping extractors
|
|
|
|
If you want to write an extractor that generically wraps another extractor
|
|
(that may or may not consume the request body) you should implement both
|
|
[`FromRequest`] and [`FromRequestParts`]:
|
|
|
|
```rust
|
|
use axum::{
|
|
Router,
|
|
body::Body,
|
|
routing::get,
|
|
extract::{Request, FromRequest, FromRequestParts},
|
|
http::{HeaderMap, request::Parts},
|
|
};
|
|
use std::time::{Instant, Duration};
|
|
|
|
// an extractor that wraps another and measures how long time it takes to run
|
|
struct Timing<E> {
|
|
extractor: E,
|
|
duration: Duration,
|
|
}
|
|
|
|
// we must implement both `FromRequestParts`
|
|
impl<S, T> FromRequestParts<S> for Timing<T>
|
|
where
|
|
S: Send + Sync,
|
|
T: FromRequestParts<S>,
|
|
{
|
|
type Rejection = T::Rejection;
|
|
|
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
|
|
let start = Instant::now();
|
|
let extractor = T::from_request_parts(parts, state).await?;
|
|
let duration = start.elapsed();
|
|
Ok(Timing {
|
|
extractor,
|
|
duration,
|
|
})
|
|
}
|
|
}
|
|
|
|
// and `FromRequest`
|
|
impl<S, T> FromRequest<S> for Timing<T>
|
|
where
|
|
S: Send + Sync,
|
|
T: FromRequest<S>,
|
|
{
|
|
type Rejection = T::Rejection;
|
|
|
|
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
|
let start = Instant::now();
|
|
let extractor = T::from_request(req, state).await?;
|
|
let duration = start.elapsed();
|
|
Ok(Timing {
|
|
extractor,
|
|
duration,
|
|
})
|
|
}
|
|
}
|
|
|
|
async fn handler(
|
|
// this uses the `FromRequestParts` impl
|
|
_: Timing<HeaderMap>,
|
|
// this uses the `FromRequest` impl
|
|
_: Timing<String>,
|
|
) {}
|
|
# let _: axum::routing::MethodRouter = axum::routing::get(handler);
|
|
```
|
|
|
|
# Logging rejections
|
|
|
|
All built-in extractors will log rejections for easier debugging. To see the
|
|
logs, enable the `tracing` feature for axum (enabled by default) and the
|
|
`axum::rejection=trace` tracing target, for example with
|
|
`RUST_LOG=info,axum::rejection=trace cargo run`.
|
|
|
|
[axum-extra]: https://docs.rs/axum-extra/latest/axum_extra/extract/index.html
|
|
[`body::Body`]: crate::body::Body
|
|
[`Bytes`]: crate::body::Bytes
|
|
[customize-extractor-error]: https://github.com/tokio-rs/axum/blob/main/examples/customize-extractor-error/src/main.rs
|
|
[`HeaderMap`]: https://docs.rs/http/latest/http/header/struct.HeaderMap.html
|
|
[`Request`]: https://docs.rs/http/latest/http/struct.Request.html
|
|
[`JsonRejection::JsonDataError`]: rejection::JsonRejection::JsonDataError
|
|
|
|
```rust
|
|
pub mod extract { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `connect_info`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"tokio\")]")`
|
|
|
|
Extractor for getting connection information from a client.
|
|
|
|
See [`Router::into_make_service_with_connect_info`] for more details.
|
|
|
|
[`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
|
|
|
```rust
|
|
pub mod connect_info { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `IntoMakeServiceWithConnectInfo`
|
|
|
|
A [`MakeService`] created from a router.
|
|
|
|
See [`Router::into_make_service_with_connect_info`] for more details.
|
|
|
|
[`MakeService`]: tower::make::MakeService
|
|
[`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
|
|
|
```rust
|
|
pub struct IntoMakeServiceWithConnectInfo<S, C> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **MakeService**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll<Result<(), <M as MakeService<Target, Request>>::MakeError>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn make_service(self: &mut Self, target: Target) -> <M as MakeService<Target, Request>>::Future { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, target: T) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<S> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<S, C> { /* ... */ }
|
|
```
|
|
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `ResponseFuture`
|
|
|
|
Response future for [`IntoMakeServiceWithConnectInfo`].
|
|
|
|
```rust
|
|
pub struct ResponseFuture<S, C> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Future**
|
|
- ```rust
|
|
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<''_>) -> std::task::Poll<<Self as >::Output> { /* ... */ }
|
|
```
|
|
|
|
- **FutureExt**
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoFuture**
|
|
- ```rust
|
|
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryFuture**
|
|
- ```rust
|
|
fn try_poll(self: Pin<&mut F>, cx: &mut Context<''_>) -> Poll<<F as Future>::Output> { /* ... */ }
|
|
```
|
|
|
|
- **TryFutureExt**
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `ConnectInfo`
|
|
|
|
Extractor for getting connection information produced by a [`Connected`].
|
|
|
|
Note this extractor requires you to use
|
|
[`Router::into_make_service_with_connect_info`] to run your app
|
|
otherwise it will fail at runtime.
|
|
|
|
See [`Router::into_make_service_with_connect_info`] for more details.
|
|
|
|
[`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
|
|
|
```rust
|
|
pub struct ConnectInfo<T>(pub T);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `T` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> ConnectInfo<T> { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Copy**
|
|
- **CryptoRng**
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Deref**
|
|
- ```rust
|
|
fn deref(self: &Self) -> &<Self as >::Target { /* ... */ }
|
|
```
|
|
|
|
- **DerefMut**
|
|
- ```rust
|
|
fn deref_mut(self: &mut Self) -> &mut <Self as >::Target { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **FromRequest**
|
|
- ```rust
|
|
fn from_request(req: Request<Body>, state: &S) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>> { /* ... */ }
|
|
```
|
|
|
|
- **FromRequestParts**
|
|
- ```rust
|
|
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **Receiver**
|
|
- **RefUnwindSafe**
|
|
- **Rng**
|
|
- **RngCore**
|
|
- ```rust
|
|
fn next_u32(self: &mut Self) -> u32 { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn next_u64(self: &mut Self) -> u64 { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn fill_bytes(self: &mut Self, dst: &mut [u8]) { /* ... */ }
|
|
```
|
|
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryCryptoRng**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryRngCore**
|
|
- ```rust
|
|
fn try_next_u32(self: &mut Self) -> Result<u32, <R as TryRngCore>::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn try_next_u64(self: &mut Self) -> Result<u64, <R as TryRngCore>::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn try_fill_bytes(self: &mut Self, dst: &mut [u8]) -> Result<(), <R as TryRngCore>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MockConnectInfo`
|
|
|
|
Middleware used to mock [`ConnectInfo`] during tests.
|
|
|
|
If you're accidentally using [`MockConnectInfo`] and
|
|
[`Router::into_make_service_with_connect_info`] at the same time then
|
|
[`Router::into_make_service_with_connect_info`] takes precedence.
|
|
|
|
# Example
|
|
|
|
```
|
|
use axum::{
|
|
Router,
|
|
extract::connect_info::{MockConnectInfo, ConnectInfo},
|
|
body::Body,
|
|
routing::get,
|
|
http::{Request, StatusCode},
|
|
};
|
|
use std::net::SocketAddr;
|
|
use tower::ServiceExt;
|
|
|
|
async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) {}
|
|
|
|
// this router you can run with `app.into_make_service_with_connect_info::<SocketAddr>()`
|
|
fn app() -> Router {
|
|
Router::new().route("/", get(handler))
|
|
}
|
|
|
|
// use this router for tests
|
|
fn test_app() -> Router {
|
|
app().layer(MockConnectInfo(SocketAddr::from(([0, 0, 0, 0], 1337))))
|
|
}
|
|
|
|
// #[tokio::test]
|
|
async fn some_test() {
|
|
let app = test_app();
|
|
|
|
let request = Request::new(Body::empty());
|
|
let response = app.oneshot(request).await.unwrap();
|
|
assert_eq!(response.status(), StatusCode::OK);
|
|
}
|
|
#
|
|
# #[tokio::main]
|
|
# async fn main() {
|
|
# some_test().await;
|
|
# }
|
|
```
|
|
|
|
[`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info
|
|
|
|
```rust
|
|
pub struct MockConnectInfo<T>(pub T);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `T` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> MockConnectInfo<T> { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Copy**
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **Layer**
|
|
- ```rust
|
|
fn layer(self: &Self, inner: S) -> <Self as >::Service { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Traits
|
|
|
|
#### Trait `Connected`
|
|
|
|
Trait that connected IO resources implement and use to produce information
|
|
about the connection.
|
|
|
|
The goal for this trait is to allow users to implement custom IO types that
|
|
can still provide the same connection metadata.
|
|
|
|
See [`Router::into_make_service_with_connect_info`] for more details.
|
|
|
|
[`Router::into_make_service_with_connect_info`]: crate::routing::Router::into_make_service_with_connect_info
|
|
|
|
```rust
|
|
pub trait Connected<T>: Clone + Send + Sync + ''static {
|
|
/* Associated items */
|
|
}
|
|
```
|
|
|
|
> This trait is not object-safe and cannot be used in dynamic trait objects.
|
|
|
|
##### Required Items
|
|
|
|
###### Required Methods
|
|
|
|
- `connect_info`: Create type holding information about the connection.
|
|
|
|
##### Implementations
|
|
|
|
This trait is implemented for the following types:
|
|
|
|
- `SocketAddr`
|
|
- `<L as >::Addr` with <''a, L, F>
|
|
- `std::net::SocketAddr`
|
|
|
|
## Module `path`
|
|
|
|
Extractor that will get captures from the URL and parse them using
|
|
[`serde`].
|
|
|
|
```rust
|
|
pub mod path { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `Path`
|
|
|
|
Extractor that will get captures from the URL and parse them using
|
|
[`serde`].
|
|
|
|
Any percent encoded parameters will be automatically decoded. The decoded
|
|
parameters must be valid UTF-8, otherwise `Path` will fail and return a `400
|
|
Bad Request` response.
|
|
|
|
# `Option<Path<T>>` behavior
|
|
|
|
You can use `Option<Path<T>>` as an extractor to allow the same handler to
|
|
be used in a route with parameters that deserialize to `T`, and another
|
|
route with no parameters at all.
|
|
|
|
# Example
|
|
|
|
These examples assume the `serde` feature of the [`uuid`] crate is enabled.
|
|
|
|
One `Path` can extract multiple captures. It is not necessary (and does
|
|
not work) to give a handler more than one `Path` argument.
|
|
|
|
[`uuid`]: https://crates.io/crates/uuid
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Path,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use uuid::Uuid;
|
|
|
|
async fn users_teams_show(
|
|
Path((user_id, team_id)): Path<(Uuid, Uuid)>,
|
|
) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new().route("/users/{user_id}/team/{team_id}", get(users_teams_show));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
If the path contains only one parameter, then you can omit the tuple.
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Path,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use uuid::Uuid;
|
|
|
|
async fn user_info(Path(user_id): Path<Uuid>) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new().route("/users/{user_id}", get(user_info));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
Path segments also can be deserialized into any type that implements
|
|
[`serde::Deserialize`]. This includes tuples and structs:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Path,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use serde::Deserialize;
|
|
use uuid::Uuid;
|
|
|
|
// Path segment labels will be matched with struct field names
|
|
#[derive(Deserialize)]
|
|
struct Params {
|
|
user_id: Uuid,
|
|
team_id: Uuid,
|
|
}
|
|
|
|
async fn users_teams_show(
|
|
Path(Params { user_id, team_id }): Path<Params>,
|
|
) {
|
|
// ...
|
|
}
|
|
|
|
// When using tuples the path segments will be matched by their position in the route
|
|
async fn users_teams_create(
|
|
Path((user_id, team_id)): Path<(String, String)>,
|
|
) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new().route(
|
|
"/users/{user_id}/team/{team_id}",
|
|
get(users_teams_show).post(users_teams_create),
|
|
);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
If you wish to capture all path parameters you can use `HashMap` or `Vec`:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Path,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use std::collections::HashMap;
|
|
|
|
async fn params_map(
|
|
Path(params): Path<HashMap<String, String>>,
|
|
) {
|
|
// ...
|
|
}
|
|
|
|
async fn params_vec(
|
|
Path(params): Path<Vec<(String, String)>>,
|
|
) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new()
|
|
.route("/users/{user_id}/team/{team_id}", get(params_map).post(params_vec));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Providing detailed rejection output
|
|
|
|
If the URI cannot be deserialized into the target type the request will be rejected and an
|
|
error response will be returned. See [`customize-path-rejection`] for an example of how to customize that error.
|
|
|
|
[`serde`]: https://crates.io/crates/serde
|
|
[`serde::Deserialize`]: https://docs.rs/serde/1.0.127/serde/trait.Deserialize.html
|
|
[`customize-path-rejection`]: https://github.com/tokio-rs/axum/blob/main/examples/customize-path-rejection/src/main.rs
|
|
|
|
```rust
|
|
pub struct Path<T>(pub T);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `T` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **CryptoRng**
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Deref**
|
|
- ```rust
|
|
fn deref(self: &Self) -> &<Self as >::Target { /* ... */ }
|
|
```
|
|
|
|
- **DerefMut**
|
|
- ```rust
|
|
fn deref_mut(self: &mut Self) -> &mut <Self as >::Target { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRequest**
|
|
- ```rust
|
|
fn from_request(req: Request<Body>, state: &S) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>> { /* ... */ }
|
|
```
|
|
|
|
- **FromRequestParts**
|
|
- ```rust
|
|
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **OptionalFromRequestParts**
|
|
- ```rust
|
|
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Option<Self>, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **Receiver**
|
|
- **RefUnwindSafe**
|
|
- **Rng**
|
|
- **RngCore**
|
|
- ```rust
|
|
fn next_u32(self: &mut Self) -> u32 { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn next_u64(self: &mut Self) -> u64 { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn fill_bytes(self: &mut Self, dst: &mut [u8]) { /* ... */ }
|
|
```
|
|
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryCryptoRng**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryRngCore**
|
|
- ```rust
|
|
fn try_next_u32(self: &mut Self) -> Result<u32, <R as TryRngCore>::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn try_next_u64(self: &mut Self) -> Result<u64, <R as TryRngCore>::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn try_fill_bytes(self: &mut Self, dst: &mut [u8]) -> Result<(), <R as TryRngCore>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `ErrorKind`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
- `NonExhaustive`
|
|
|
|
The kinds of errors that can happen we deserializing into a [`Path`].
|
|
|
|
This type is obtained through [`FailedToDeserializePathParams::kind`] or
|
|
[`FailedToDeserializePathParams::into_kind`] and is useful for building
|
|
more precise error messages.
|
|
|
|
```rust
|
|
pub enum ErrorKind {
|
|
WrongNumberOfParameters {
|
|
got: usize,
|
|
expected: usize,
|
|
},
|
|
ParseErrorAtKey {
|
|
key: String,
|
|
value: String,
|
|
expected_type: &''static str,
|
|
},
|
|
ParseErrorAtIndex {
|
|
index: usize,
|
|
value: String,
|
|
expected_type: &''static str,
|
|
},
|
|
ParseError {
|
|
value: String,
|
|
expected_type: &''static str,
|
|
},
|
|
InvalidUtf8InPathParam {
|
|
key: String,
|
|
},
|
|
UnsupportedType {
|
|
name: &''static str,
|
|
},
|
|
DeserializeError {
|
|
key: String,
|
|
value: String,
|
|
message: String,
|
|
},
|
|
Message(String),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `WrongNumberOfParameters`
|
|
|
|
The URI contained the wrong number of parameters.
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `got` | `usize` | The number of actual parameters in the URI. |
|
|
| `expected` | `usize` | The number of expected parameters. |
|
|
|
|
###### `ParseErrorAtKey`
|
|
|
|
Failed to parse the value at a specific key into the expected type.
|
|
|
|
This variant is used when deserializing into types that have named fields, such as structs.
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `key` | `String` | The key at which the value was located. |
|
|
| `value` | `String` | The value from the URI. |
|
|
| `expected_type` | `&''static str` | The expected type of the value. |
|
|
|
|
###### `ParseErrorAtIndex`
|
|
|
|
Failed to parse the value at a specific index into the expected type.
|
|
|
|
This variant is used when deserializing into sequence types, such as tuples.
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `index` | `usize` | The index at which the value was located. |
|
|
| `value` | `String` | The value from the URI. |
|
|
| `expected_type` | `&''static str` | The expected type of the value. |
|
|
|
|
###### `ParseError`
|
|
|
|
Failed to parse a value into the expected type.
|
|
|
|
This variant is used when deserializing into a primitive type (such as `String` and `u32`).
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `value` | `String` | The value from the URI. |
|
|
| `expected_type` | `&''static str` | The expected type of the value. |
|
|
|
|
###### `InvalidUtf8InPathParam`
|
|
|
|
A parameter contained text that, once percent decoded, wasn't valid UTF-8.
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `key` | `String` | The key at which the invalid value was located. |
|
|
|
|
###### `UnsupportedType`
|
|
|
|
Tried to serialize into an unsupported type such as nested maps.
|
|
|
|
This error kind is caused by programmer errors and thus gets converted into a `500 Internal
|
|
Server Error` response.
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `name` | `&''static str` | The name of the unsupported type. |
|
|
|
|
###### `DeserializeError`
|
|
|
|
Failed to deserialize the value with a custom deserialization error.
|
|
|
|
Fields:
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `key` | `String` | The key at which the invalid value was located. |
|
|
| `value` | `String` | The value that failed to deserialize. |
|
|
| `message` | `String` | The deserializaation failure message. |
|
|
|
|
###### `Message`
|
|
|
|
Catch-all variant for errors that don't fit any other variant.
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `String` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Eq**
|
|
- **Equivalent**
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PartialEq**
|
|
- ```rust
|
|
fn eq(self: &Self, other: &ErrorKind) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **StructuralPartialEq**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `FailedToDeserializePathParams`
|
|
|
|
Rejection type for [`Path`] if the captured routes params couldn't be deserialized
|
|
into the expected type.
|
|
|
|
```rust
|
|
pub struct FailedToDeserializePathParams(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn kind(self: &Self) -> &ErrorKind { /* ... */ }
|
|
```
|
|
Get a reference to the underlying error kind.
|
|
|
|
- ```rust
|
|
pub fn into_kind(self: Self) -> ErrorKind { /* ... */ }
|
|
```
|
|
Convert this error into the underlying error kind.
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializePathParams) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `RawPathParams`
|
|
|
|
Extractor that will get captures from the URL without deserializing them.
|
|
|
|
In general you should prefer to use [`Path`] as it is higher level, however `RawPathParams` is
|
|
suitable if just want the raw params without deserializing them and thus saving some
|
|
allocations.
|
|
|
|
Any percent encoded parameters will be automatically decoded. The decoded parameters must be
|
|
valid UTF-8, otherwise `RawPathParams` will fail and return a `400 Bad Request` response.
|
|
|
|
# Example
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::RawPathParams,
|
|
routing::get,
|
|
Router,
|
|
};
|
|
|
|
async fn users_teams_show(params: RawPathParams) {
|
|
for (key, value) in ¶ms {
|
|
println!("{key:?} = {value:?}");
|
|
}
|
|
}
|
|
|
|
let app = Router::new().route("/users/{user_id}/team/{team_id}", get(users_teams_show));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
```rust
|
|
pub struct RawPathParams(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn iter(self: &Self) -> RawPathParamsIter<''_> { /* ... */ }
|
|
```
|
|
Get an iterator over the path parameters.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRequest**
|
|
- ```rust
|
|
fn from_request(req: Request<Body>, state: &S) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>> { /* ... */ }
|
|
```
|
|
|
|
- **FromRequestParts**
|
|
- ```rust
|
|
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoIterator**
|
|
- ```rust
|
|
fn into_iter(self: Self) -> <Self as >::IntoIter { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `RawPathParamsIter`
|
|
|
|
An iterator over raw path parameters.
|
|
|
|
Created with [`RawPathParams::iter`].
|
|
|
|
```rust
|
|
pub struct RawPathParamsIter<''a>(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoIterator**
|
|
- ```rust
|
|
fn into_iter(self: Self) -> I { /* ... */ }
|
|
```
|
|
|
|
- **Iterator**
|
|
- ```rust
|
|
fn next(self: &mut Self) -> Option<<Self as >::Item> { /* ... */ }
|
|
```
|
|
|
|
- **IteratorRandom**
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidUtf8InPathParam`
|
|
|
|
Rejection used by [`RawPathParams`] if a parameter contained text that, once percent decoded,
|
|
wasn't valid UTF-8.
|
|
|
|
```rust
|
|
pub struct InvalidUtf8InPathParam {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidUtf8InPathParam) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
## Module `rejection`
|
|
|
|
Rejection response types.
|
|
|
|
```rust
|
|
pub mod rejection { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `JsonDataError`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"json\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"json\"))]")`
|
|
|
|
Rejection type for [`Json`](super::Json).
|
|
|
|
This rejection is used if the request body is syntactically valid JSON but couldn't be
|
|
deserialized into the target type.
|
|
|
|
```rust
|
|
pub struct JsonDataError(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: JsonDataError) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `JsonSyntaxError`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"json\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"json\"))]")`
|
|
|
|
Rejection type for [`Json`](super::Json).
|
|
|
|
This rejection is used if the request body didn't contain syntactically valid JSON.
|
|
|
|
```rust
|
|
pub struct JsonSyntaxError(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: JsonSyntaxError) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MissingJsonContentType`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"json\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"json\"))]")`
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`Json`](super::Json) used if the `Content-Type`
|
|
header is missing.
|
|
|
|
```rust
|
|
pub struct MissingJsonContentType;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MissingJsonContentType) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MissingExtension`
|
|
|
|
Rejection type for [`Extension`](super::Extension) if an expected
|
|
request extension was not found.
|
|
|
|
```rust
|
|
pub struct MissingExtension(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MissingExtension) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MissingPathParams`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type used if axum's internal representation of path parameters
|
|
is missing. This is commonly caused by extracting `Request<_>`. `Path`
|
|
must be extracted first.
|
|
|
|
```rust
|
|
pub struct MissingPathParams;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MissingPathParams) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: MissingPathParams) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidFormContentType`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`Form`](super::Form) or [`RawForm`](super::RawForm)
|
|
used if the `Content-Type` header is missing
|
|
or its value is not `application/x-www-form-urlencoded`.
|
|
|
|
```rust
|
|
pub struct InvalidFormContentType;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidFormContentType) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidFormContentType) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `FailedToDeserializeForm`
|
|
|
|
Rejection type used if the [`Form`](super::Form) extractor is unable to
|
|
deserialize the form into the target type.
|
|
|
|
```rust
|
|
pub struct FailedToDeserializeForm(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializeForm) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `FailedToDeserializeFormBody`
|
|
|
|
Rejection type used if the [`Form`](super::Form) extractor is unable to
|
|
deserialize the form body into the target type.
|
|
|
|
```rust
|
|
pub struct FailedToDeserializeFormBody(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializeFormBody) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `FailedToDeserializeQueryString`
|
|
|
|
Rejection type used if the [`Query`](super::Query) extractor is unable to
|
|
deserialize the query string into the target type.
|
|
|
|
```rust
|
|
pub struct FailedToDeserializeQueryString(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializeQueryString) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `QueryRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`Query`](super::Query).
|
|
|
|
Contains one variant for each way the [`Query`](super::Query) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum QueryRejection {
|
|
FailedToDeserializeQueryString(FailedToDeserializeQueryString),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `FailedToDeserializeQueryString`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `FailedToDeserializeQueryString` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializeQueryString) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `FormRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`Form`](super::Form).
|
|
|
|
Contains one variant for each way the [`Form`](super::Form) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum FormRejection {
|
|
InvalidFormContentType(InvalidFormContentType),
|
|
FailedToDeserializeForm(FailedToDeserializeForm),
|
|
FailedToDeserializeFormBody(FailedToDeserializeFormBody),
|
|
BytesRejection(BytesRejection),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `InvalidFormContentType`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidFormContentType` | |
|
|
|
|
###### `FailedToDeserializeForm`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `FailedToDeserializeForm` | |
|
|
|
|
###### `FailedToDeserializeFormBody`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `FailedToDeserializeFormBody` | |
|
|
|
|
###### `BytesRejection`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `BytesRejection` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidFormContentType) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializeForm) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializeFormBody) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: BytesRejection) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `RawFormRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`RawForm`](super::RawForm).
|
|
|
|
Contains one variant for each way the [`RawForm`](super::RawForm) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum RawFormRejection {
|
|
InvalidFormContentType(InvalidFormContentType),
|
|
BytesRejection(BytesRejection),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `InvalidFormContentType`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidFormContentType` | |
|
|
|
|
###### `BytesRejection`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `BytesRejection` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidFormContentType) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: BytesRejection) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `JsonRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"json\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"json\"))]")`
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`Json`](super::Json).
|
|
|
|
Contains one variant for each way the [`Json`](super::Json) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum JsonRejection {
|
|
JsonDataError(JsonDataError),
|
|
JsonSyntaxError(JsonSyntaxError),
|
|
MissingJsonContentType(MissingJsonContentType),
|
|
BytesRejection(BytesRejection),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `JsonDataError`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `JsonDataError` | |
|
|
|
|
###### `JsonSyntaxError`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `JsonSyntaxError` | |
|
|
|
|
###### `MissingJsonContentType`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MissingJsonContentType` | |
|
|
|
|
###### `BytesRejection`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `BytesRejection` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: JsonDataError) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: JsonSyntaxError) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: MissingJsonContentType) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: BytesRejection) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `ExtensionRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`Extension`](super::Extension).
|
|
|
|
Contains one variant for each way the [`Extension`](super::Extension) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum ExtensionRejection {
|
|
MissingExtension(MissingExtension),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `MissingExtension`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MissingExtension` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MissingExtension) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `PathRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`Path`](super::Path).
|
|
|
|
Contains one variant for each way the [`Path`](super::Path) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum PathRejection {
|
|
FailedToDeserializePathParams(FailedToDeserializePathParams),
|
|
MissingPathParams(MissingPathParams),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `FailedToDeserializePathParams`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `FailedToDeserializePathParams` | |
|
|
|
|
###### `MissingPathParams`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MissingPathParams` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: FailedToDeserializePathParams) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: MissingPathParams) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `RawPathParamsRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`RawPathParams`](super::RawPathParams).
|
|
|
|
Contains one variant for each way the [`RawPathParams`](super::RawPathParams) extractor
|
|
can fail.
|
|
|
|
```rust
|
|
pub enum RawPathParamsRejection {
|
|
InvalidUtf8InPathParam(InvalidUtf8InPathParam),
|
|
MissingPathParams(MissingPathParams),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `InvalidUtf8InPathParam`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidUtf8InPathParam` | |
|
|
|
|
###### `MissingPathParams`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MissingPathParams` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidUtf8InPathParam) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: MissingPathParams) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MatchedPathMissing`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"matched-path\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"matched-path\"))]")`
|
|
- `NonExhaustive`
|
|
|
|
Rejection if no matched path could be found.
|
|
|
|
See [`MatchedPath`](super::MatchedPath) for more details.
|
|
|
|
```rust
|
|
pub struct MatchedPathMissing;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MatchedPathMissing) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `MatchedPathRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"matched-path\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"matched-path\"))]")`
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`MatchedPath`](super::MatchedPath).
|
|
|
|
```rust
|
|
pub enum MatchedPathRejection {
|
|
MatchedPathMissing(MatchedPathMissing),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `MatchedPathMissing`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MatchedPathMissing` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MatchedPathMissing) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `NestedPathRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`NestedPath`](super::NestedPath).
|
|
|
|
This rejection is used if the matched route wasn't nested.
|
|
|
|
```rust
|
|
pub struct NestedPathRejection;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Re-exports
|
|
|
|
#### Re-export `FailedToDeserializePathParams`
|
|
|
|
```rust
|
|
pub use crate::extract::path::FailedToDeserializePathParams;
|
|
```
|
|
|
|
#### Re-export `InvalidUtf8InPathParam`
|
|
|
|
```rust
|
|
pub use crate::extract::path::InvalidUtf8InPathParam;
|
|
```
|
|
|
|
#### Re-export `axum_core::extract::rejection::*`
|
|
|
|
```rust
|
|
pub use axum_core::extract::rejection::*;
|
|
```
|
|
|
|
## Module `ws`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"ws\")]")`
|
|
|
|
Handle WebSocket connections.
|
|
|
|
# Example
|
|
|
|
```
|
|
use axum::{
|
|
extract::ws::{WebSocketUpgrade, WebSocket},
|
|
routing::any,
|
|
response::{IntoResponse, Response},
|
|
Router,
|
|
};
|
|
|
|
let app = Router::new().route("/ws", any(handler));
|
|
|
|
async fn handler(ws: WebSocketUpgrade) -> Response {
|
|
ws.on_upgrade(handle_socket)
|
|
}
|
|
|
|
async fn handle_socket(mut socket: WebSocket) {
|
|
while let Some(msg) = socket.recv().await {
|
|
let msg = if let Ok(msg) = msg {
|
|
msg
|
|
} else {
|
|
// client disconnected
|
|
return;
|
|
};
|
|
|
|
if socket.send(msg).await.is_err() {
|
|
// client disconnected
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Passing data and/or state to an `on_upgrade` callback
|
|
|
|
```
|
|
use axum::{
|
|
extract::{ws::{WebSocketUpgrade, WebSocket}, State},
|
|
response::Response,
|
|
routing::any,
|
|
Router,
|
|
};
|
|
|
|
#[derive(Clone)]
|
|
struct AppState {
|
|
// ...
|
|
}
|
|
|
|
async fn handler(ws: WebSocketUpgrade, State(state): State<AppState>) -> Response {
|
|
ws.on_upgrade(|socket| handle_socket(socket, state))
|
|
}
|
|
|
|
async fn handle_socket(socket: WebSocket, state: AppState) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new()
|
|
.route("/ws", any(handler))
|
|
.with_state(AppState { /* ... */ });
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Read and write concurrently
|
|
|
|
If you need to read and write concurrently from a [`WebSocket`] you can use
|
|
[`StreamExt::split`]:
|
|
|
|
```rust,no_run
|
|
use axum::{Error, extract::ws::{WebSocket, Message}};
|
|
use futures_util::{sink::SinkExt, stream::{StreamExt, SplitSink, SplitStream}};
|
|
|
|
async fn handle_socket(mut socket: WebSocket) {
|
|
let (mut sender, mut receiver) = socket.split();
|
|
|
|
tokio::spawn(write(sender));
|
|
tokio::spawn(read(receiver));
|
|
}
|
|
|
|
async fn read(receiver: SplitStream<WebSocket>) {
|
|
// ...
|
|
}
|
|
|
|
async fn write(sender: SplitSink<WebSocket, Message>) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
[`StreamExt::split`]: https://docs.rs/futures/0.3.17/futures/stream/trait.StreamExt.html#method.split
|
|
|
|
```rust
|
|
pub mod ws { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `rejection`
|
|
|
|
WebSocket specific rejections.
|
|
|
|
```rust
|
|
pub mod rejection { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `MethodNotGet`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct MethodNotGet;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MethodNotGet) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MethodNotConnect`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct MethodNotConnect;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MethodNotConnect) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidConnectionHeader`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct InvalidConnectionHeader;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidConnectionHeader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidUpgradeHeader`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct InvalidUpgradeHeader;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidUpgradeHeader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidProtocolPseudoheader`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct InvalidProtocolPseudoheader;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidProtocolPseudoheader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidWebSocketVersionHeader`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct InvalidWebSocketVersionHeader;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidWebSocketVersionHeader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `WebSocketKeyHeaderMissing`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
```rust
|
|
pub struct WebSocketKeyHeaderMissing;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: WebSocketKeyHeaderMissing) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `ConnectionNotUpgradable`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
This rejection is returned if the connection cannot be upgraded for example if the
|
|
request is HTTP/1.0.
|
|
|
|
See [MDN] for more details about connection upgrades.
|
|
|
|
[MDN]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
|
|
|
|
```rust
|
|
pub struct ConnectionNotUpgradable;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: ConnectionNotUpgradable) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `WebSocketUpgradeRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`WebSocketUpgrade`](super::WebSocketUpgrade).
|
|
|
|
Contains one variant for each way the [`WebSocketUpgrade`](super::WebSocketUpgrade)
|
|
extractor can fail.
|
|
|
|
```rust
|
|
pub enum WebSocketUpgradeRejection {
|
|
MethodNotGet(MethodNotGet),
|
|
MethodNotConnect(MethodNotConnect),
|
|
InvalidConnectionHeader(InvalidConnectionHeader),
|
|
InvalidUpgradeHeader(InvalidUpgradeHeader),
|
|
InvalidProtocolPseudoheader(InvalidProtocolPseudoheader),
|
|
InvalidWebSocketVersionHeader(InvalidWebSocketVersionHeader),
|
|
WebSocketKeyHeaderMissing(WebSocketKeyHeaderMissing),
|
|
ConnectionNotUpgradable(ConnectionNotUpgradable),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `MethodNotGet`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MethodNotGet` | |
|
|
|
|
###### `MethodNotConnect`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `MethodNotConnect` | |
|
|
|
|
###### `InvalidConnectionHeader`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidConnectionHeader` | |
|
|
|
|
###### `InvalidUpgradeHeader`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidUpgradeHeader` | |
|
|
|
|
###### `InvalidProtocolPseudoheader`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidProtocolPseudoheader` | |
|
|
|
|
###### `InvalidWebSocketVersionHeader`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidWebSocketVersionHeader` | |
|
|
|
|
###### `WebSocketKeyHeaderMissing`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `WebSocketKeyHeaderMissing` | |
|
|
|
|
###### `ConnectionNotUpgradable`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `ConnectionNotUpgradable` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: MethodNotGet) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: MethodNotConnect) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidConnectionHeader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidUpgradeHeader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidProtocolPseudoheader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidWebSocketVersionHeader) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: WebSocketKeyHeaderMissing) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: ConnectionNotUpgradable) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
## Module `close_code`
|
|
|
|
Constants for [`CloseCode`]s.
|
|
|
|
[`CloseCode`]: super::CloseCode
|
|
|
|
```rust
|
|
pub mod close_code { /* ... */ }
|
|
```
|
|
|
|
### Constants and Statics
|
|
|
|
#### Constant `NORMAL`
|
|
|
|
Indicates a normal closure, meaning that the purpose for which the connection was
|
|
established has been fulfilled.
|
|
|
|
```rust
|
|
pub const NORMAL: u16 = 1000;
|
|
```
|
|
|
|
#### Constant `AWAY`
|
|
|
|
Indicates that an endpoint is "going away", such as a server going down or a browser having
|
|
navigated away from a page.
|
|
|
|
```rust
|
|
pub const AWAY: u16 = 1001;
|
|
```
|
|
|
|
#### Constant `PROTOCOL`
|
|
|
|
Indicates that an endpoint is terminating the connection due to a protocol error.
|
|
|
|
```rust
|
|
pub const PROTOCOL: u16 = 1002;
|
|
```
|
|
|
|
#### Constant `UNSUPPORTED`
|
|
|
|
Indicates that an endpoint is terminating the connection because it has received a type of
|
|
data that it cannot accept.
|
|
|
|
For example, an endpoint MAY send this if it understands only text data, but receives a binary message.
|
|
|
|
```rust
|
|
pub const UNSUPPORTED: u16 = 1003;
|
|
```
|
|
|
|
#### Constant `STATUS`
|
|
|
|
Indicates that no status code was included in a closing frame.
|
|
|
|
```rust
|
|
pub const STATUS: u16 = 1005;
|
|
```
|
|
|
|
#### Constant `ABNORMAL`
|
|
|
|
Indicates an abnormal closure.
|
|
|
|
```rust
|
|
pub const ABNORMAL: u16 = 1006;
|
|
```
|
|
|
|
#### Constant `INVALID`
|
|
|
|
Indicates that an endpoint is terminating the connection because it has received data
|
|
within a message that was not consistent with the type of the message.
|
|
|
|
For example, an endpoint received non-UTF-8 RFC3629 data within a text message.
|
|
|
|
```rust
|
|
pub const INVALID: u16 = 1007;
|
|
```
|
|
|
|
#### Constant `POLICY`
|
|
|
|
Indicates that an endpoint is terminating the connection because it has received a message
|
|
that violates its policy.
|
|
|
|
This is a generic status code that can be returned when there is
|
|
no other more suitable status code (e.g., `UNSUPPORTED` or `SIZE`) or if there is a need to
|
|
hide specific details about the policy.
|
|
|
|
```rust
|
|
pub const POLICY: u16 = 1008;
|
|
```
|
|
|
|
#### Constant `SIZE`
|
|
|
|
Indicates that an endpoint is terminating the connection because it has received a message
|
|
that is too big for it to process.
|
|
|
|
```rust
|
|
pub const SIZE: u16 = 1009;
|
|
```
|
|
|
|
#### Constant `EXTENSION`
|
|
|
|
Indicates that an endpoint (client) is terminating the connection because the server
|
|
did not respond to extension negotiation correctly.
|
|
|
|
Specifically, the client has expected the server to negotiate one or more extension(s),
|
|
but the server didn't return them in the response message of the WebSocket handshake.
|
|
The list of extensions that are needed should be given as the reason for closing.
|
|
Note that this status code is not used by the server,
|
|
because it can fail the WebSocket handshake instead.
|
|
|
|
```rust
|
|
pub const EXTENSION: u16 = 1010;
|
|
```
|
|
|
|
#### Constant `ERROR`
|
|
|
|
Indicates that a server is terminating the connection because it encountered an unexpected
|
|
condition that prevented it from fulfilling the request.
|
|
|
|
```rust
|
|
pub const ERROR: u16 = 1011;
|
|
```
|
|
|
|
#### Constant `RESTART`
|
|
|
|
Indicates that the server is restarting.
|
|
|
|
```rust
|
|
pub const RESTART: u16 = 1012;
|
|
```
|
|
|
|
#### Constant `AGAIN`
|
|
|
|
Indicates that the server is overloaded and the client should either connect to a different
|
|
IP (when multiple targets exist), or reconnect to the same IP when a user has performed an
|
|
action.
|
|
|
|
```rust
|
|
pub const AGAIN: u16 = 1013;
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `WebSocketUpgrade`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"ws\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"ws\"))]")`
|
|
- `MustUse { reason: None }`
|
|
|
|
Extractor for establishing WebSocket connections.
|
|
|
|
For HTTP/1.1 requests, this extractor requires the request method to be `GET`;
|
|
in later versions, `CONNECT` is used instead.
|
|
To support both, it should be used with [`any`](crate::routing::any).
|
|
|
|
See the [module docs](self) for an example.
|
|
|
|
[`MethodFilter`]: crate::routing::MethodFilter
|
|
|
|
```rust
|
|
pub struct WebSocketUpgrade<F = DefaultOnFailedUpgrade> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn read_buffer_size(self: Self, size: usize) -> Self { /* ... */ }
|
|
```
|
|
Read buffer capacity. The default value is 128KiB
|
|
|
|
- ```rust
|
|
pub fn write_buffer_size(self: Self, size: usize) -> Self { /* ... */ }
|
|
```
|
|
The target minimum size of the write buffer to reach before writing the data
|
|
|
|
- ```rust
|
|
pub fn max_write_buffer_size(self: Self, max: usize) -> Self { /* ... */ }
|
|
```
|
|
The max size of the write buffer in bytes. Setting this can provide backpressure
|
|
|
|
- ```rust
|
|
pub fn max_message_size(self: Self, max: usize) -> Self { /* ... */ }
|
|
```
|
|
Set the maximum message size (defaults to 64 megabytes)
|
|
|
|
- ```rust
|
|
pub fn max_frame_size(self: Self, max: usize) -> Self { /* ... */ }
|
|
```
|
|
Set the maximum frame size (defaults to 16 megabytes)
|
|
|
|
- ```rust
|
|
pub fn accept_unmasked_frames(self: Self, accept: bool) -> Self { /* ... */ }
|
|
```
|
|
Allow server to accept unmasked frames (defaults to false)
|
|
|
|
- ```rust
|
|
pub fn protocols<I>(self: Self, protocols: I) -> Self
|
|
where
|
|
I: IntoIterator,
|
|
<I as >::Item: Into<Cow<''static, str>> { /* ... */ }
|
|
```
|
|
Set the known protocols.
|
|
|
|
- ```rust
|
|
pub fn selected_protocol(self: &Self) -> Option<&HeaderValue> { /* ... */ }
|
|
```
|
|
Return the selected WebSocket subprotocol, if one has been chosen.
|
|
|
|
- ```rust
|
|
pub fn on_failed_upgrade<C>(self: Self, callback: C) -> WebSocketUpgrade<C>
|
|
where
|
|
C: OnFailedUpgrade { /* ... */ }
|
|
```
|
|
Provide a callback to call if upgrading the connection fails.
|
|
|
|
- ```rust
|
|
pub fn on_upgrade<C, Fut>(self: Self, callback: C) -> Response
|
|
where
|
|
C: FnOnce(WebSocket) -> Fut + Send + ''static,
|
|
Fut: Future<Output = ()> + Send + ''static,
|
|
F: OnFailedUpgrade { /* ... */ }
|
|
```
|
|
Finalize upgrading the connection and call the provided callback with
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRequest**
|
|
- ```rust
|
|
fn from_request(req: Request<Body>, state: &S) -> impl Future<Output = Result<T, <T as FromRequest<S, ViaParts>>::Rejection>> { /* ... */ }
|
|
```
|
|
|
|
- **FromRequestParts**
|
|
- ```rust
|
|
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `DefaultOnFailedUpgrade`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
The default `OnFailedUpgrade` used by `WebSocketUpgrade`.
|
|
|
|
It simply ignores the error.
|
|
|
|
```rust
|
|
pub struct DefaultOnFailedUpgrade;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **OnFailedUpgrade**
|
|
- ```rust
|
|
fn call(self: Self, _error: Error) { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `WebSocket`
|
|
|
|
A stream of WebSocket messages.
|
|
|
|
See [the module level documentation](self) for more details.
|
|
|
|
```rust
|
|
pub struct WebSocket {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub async fn recv(self: &mut Self) -> Option<Result<Message, Error>> { /* ... */ }
|
|
```
|
|
Receive another message.
|
|
|
|
- ```rust
|
|
pub async fn send(self: &mut Self, msg: Message) -> Result<(), Error> { /* ... */ }
|
|
```
|
|
Send a message.
|
|
|
|
- ```rust
|
|
pub fn protocol(self: &Self) -> Option<&HeaderValue> { /* ... */ }
|
|
```
|
|
Return the selected WebSocket subprotocol, if one has been chosen.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FusedStream**
|
|
- ```rust
|
|
fn is_terminated(self: &Self) -> bool { /* ... */ }
|
|
```
|
|
Returns true if the websocket has been terminated.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sink**
|
|
- ```rust
|
|
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn start_send(self: Pin<&mut Self>, item: Message) -> Result<(), <Self as >::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- **SinkExt**
|
|
- **Stream**
|
|
- ```rust
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Option<<Self as >::Item>> { /* ... */ }
|
|
```
|
|
|
|
- **StreamExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryStream**
|
|
- ```rust
|
|
fn try_poll_next(self: Pin<&mut S>, cx: &mut Context<''_>) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>> { /* ... */ }
|
|
```
|
|
|
|
- **TryStreamExt**
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `Utf8Bytes`
|
|
|
|
UTF-8 wrapper for [Bytes].
|
|
|
|
An [Utf8Bytes] is always guaranteed to contain valid UTF-8.
|
|
|
|
```rust
|
|
pub struct Utf8Bytes(/* private field */);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `private` | *Private field* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub const fn from_static(str: &''static str) -> Self { /* ... */ }
|
|
```
|
|
Creates from a static str.
|
|
|
|
- ```rust
|
|
pub fn as_str(self: &Self) -> &str { /* ... */ }
|
|
```
|
|
Returns as a string slice.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Utf8Bytes { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Utf8Bytes { /* ... */ }
|
|
```
|
|
|
|
- **Deref**
|
|
- ```rust
|
|
fn deref(self: &Self) -> &<Self as >::Target { /* ... */ }
|
|
```
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Eq**
|
|
- **Equivalent**
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(s: String) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(s: &str) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(s: &String) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(Utf8Bytes: Utf8Bytes) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PartialEq**
|
|
- ```rust
|
|
fn eq(self: &Self, other: &Utf8Bytes) -> bool { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn eq(self: &Self, other: &T) -> bool { /* ... */ }
|
|
```
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **Receiver**
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **StructuralPartialEq**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn try_from(bytes: Bytes) -> Result<Self, <Self as >::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn try_from(v: Vec<u8>) -> Result<Self, <Self as >::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Type Alias `CloseCode`
|
|
|
|
Status code used to indicate why an endpoint is closing the WebSocket connection.
|
|
|
|
```rust
|
|
pub type CloseCode = u16;
|
|
```
|
|
|
|
#### Struct `CloseFrame`
|
|
|
|
A struct representing the close command.
|
|
|
|
```rust
|
|
pub struct CloseFrame {
|
|
pub code: CloseCode,
|
|
pub reason: Utf8Bytes,
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| `code` | `CloseCode` | The reason as a code. |
|
|
| `reason` | `Utf8Bytes` | The reason as text string. |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> CloseFrame { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Eq**
|
|
- **Equivalent**
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PartialEq**
|
|
- ```rust
|
|
fn eq(self: &Self, other: &CloseFrame) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **StructuralPartialEq**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `Message`
|
|
|
|
A WebSocket message.
|
|
|
|
```rust
|
|
pub enum Message {
|
|
Text(Utf8Bytes),
|
|
Binary(crate::body::Bytes),
|
|
Ping(crate::body::Bytes),
|
|
Pong(crate::body::Bytes),
|
|
Close(Option<CloseFrame>),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `Text`
|
|
|
|
A text WebSocket message
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `Utf8Bytes` | |
|
|
|
|
###### `Binary`
|
|
|
|
A binary WebSocket message
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `crate::body::Bytes` | |
|
|
|
|
###### `Ping`
|
|
|
|
A ping message with the specified payload
|
|
|
|
The payload here must have a length less than 125 bytes.
|
|
|
|
Ping messages will be automatically responded to by the server, so you do not have to worry
|
|
about dealing with them yourself.
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `crate::body::Bytes` | |
|
|
|
|
###### `Pong`
|
|
|
|
A pong message with the specified payload
|
|
|
|
The payload here must have a length less than 125 bytes.
|
|
|
|
Pong messages will be automatically sent to the client if a ping message is received, so
|
|
you do not have to worry about constructing them yourself unless you want to implement a
|
|
[unidirectional heartbeat](https://tools.ietf.org/html/rfc6455#section-5.5.3).
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `crate::body::Bytes` | |
|
|
|
|
###### `Close`
|
|
|
|
A close message with the optional close frame.
|
|
|
|
You may "uncleanly" close a WebSocket connection at any time
|
|
by simply dropping the [`WebSocket`].
|
|
However, you may also use the graceful closing protocol, in which
|
|
1. peer A sends a close frame, and does not send any further messages;
|
|
2. peer B responds with a close frame, and does not send any further messages;
|
|
3. peer A processes the remaining messages sent by peer B, before finally
|
|
4. both peers close the connection.
|
|
|
|
After sending a close frame,
|
|
you may still read messages,
|
|
but attempts to send another message will error.
|
|
After receiving a close frame,
|
|
axum will automatically respond with a close frame if necessary
|
|
(you do not have to deal with this yourself).
|
|
Since no further messages will be received,
|
|
you may either do nothing
|
|
or explicitly drop the connection.
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `Option<CloseFrame>` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn into_data(self: Self) -> Bytes { /* ... */ }
|
|
```
|
|
Consume the WebSocket and return it as binary data.
|
|
|
|
- ```rust
|
|
pub fn into_text(self: Self) -> Result<Utf8Bytes, Error> { /* ... */ }
|
|
```
|
|
Attempt to consume the WebSocket message and convert it to a Utf8Bytes.
|
|
|
|
- ```rust
|
|
pub fn to_text(self: &Self) -> Result<&str, Error> { /* ... */ }
|
|
```
|
|
Attempt to get a &str from the WebSocket message,
|
|
|
|
- ```rust
|
|
pub fn text<S>(string: S) -> Message
|
|
where
|
|
S: Into<Utf8Bytes> { /* ... */ }
|
|
```
|
|
Create a new text WebSocket message from a stringable.
|
|
|
|
- ```rust
|
|
pub fn binary<B>(bin: B) -> Message
|
|
where
|
|
B: Into<Bytes> { /* ... */ }
|
|
```
|
|
Create a new binary WebSocket message by converting to `Bytes`.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Message { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Eq**
|
|
- **Equivalent**
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn equivalent(self: &Self, key: &K) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(string: String) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(string: &''s str) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(data: &''b [u8]) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(data: Bytes) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(data: Vec<u8>) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(msg: Message) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PartialEq**
|
|
- ```rust
|
|
fn eq(self: &Self, other: &Message) -> bool { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sink**
|
|
- ```rust
|
|
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn start_send(self: Pin<&mut Self>, item: Message) -> Result<(), <Self as >::Error> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- **StructuralPartialEq**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Traits
|
|
|
|
#### Trait `OnFailedUpgrade`
|
|
|
|
What to do when a connection upgrade fails.
|
|
|
|
See [`WebSocketUpgrade::on_failed_upgrade`] for more details.
|
|
|
|
```rust
|
|
pub trait OnFailedUpgrade: Send + ''static {
|
|
/* Associated items */
|
|
}
|
|
```
|
|
|
|
##### Required Items
|
|
|
|
###### Required Methods
|
|
|
|
- `call`: Call the callback.
|
|
|
|
##### Implementations
|
|
|
|
This trait is implemented for the following types:
|
|
|
|
- `F` with <F>
|
|
- `DefaultOnFailedUpgrade`
|
|
|
|
## Module `multipart`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"multipart\")]")`
|
|
|
|
Extractor that parses `multipart/form-data` requests commonly used with file uploads.
|
|
|
|
See [`Multipart`] for more details.
|
|
|
|
```rust
|
|
pub mod multipart { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `Multipart`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_attr_trace>(docsrs, doc(cfg(feature = \"multipart\")))]")`
|
|
- `Other("#[doc(cfg(feature = \"multipart\"))]")`
|
|
|
|
Extractor that parses `multipart/form-data` requests (commonly used with file uploads).
|
|
|
|
⚠️ Since extracting multipart form data from the request requires consuming the body, the
|
|
`Multipart` extractor must be *last* if there are multiple extractors in a handler.
|
|
See ["the order of extractors"][order-of-extractors]
|
|
|
|
[order-of-extractors]: crate::extract#the-order-of-extractors
|
|
|
|
# Example
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
extract::Multipart,
|
|
routing::post,
|
|
Router,
|
|
};
|
|
use futures_util::stream::StreamExt;
|
|
|
|
async fn upload(mut multipart: Multipart) {
|
|
while let Some(mut field) = multipart.next_field().await.unwrap() {
|
|
let name = field.name().unwrap().to_string();
|
|
let data = field.bytes().await.unwrap();
|
|
|
|
println!("Length of `{}` is {} bytes", name, data.len());
|
|
}
|
|
}
|
|
|
|
let app = Router::new().route("/upload", post(upload));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Large Files
|
|
|
|
For security reasons, by default, `Multipart` limits the request body size to 2MB.
|
|
See [`DefaultBodyLimit`][default-body-limit] for how to configure this limit.
|
|
|
|
[default-body-limit]: crate::extract::DefaultBodyLimit
|
|
|
|
```rust
|
|
pub struct Multipart {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub async fn next_field(self: &mut Self) -> Result<Option<Field<''_>>, MultipartError> { /* ... */ }
|
|
```
|
|
Yields the next [`Field`] if available.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRequest**
|
|
- ```rust
|
|
async fn from_request(req: Request, _state: &S) -> Result<Self, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **OptionalFromRequest**
|
|
- ```rust
|
|
async fn from_request(req: Request, _state: &S) -> Result<Option<Self>, <Self as >::Rejection> { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `Field`
|
|
|
|
A single field in a multipart stream.
|
|
|
|
```rust
|
|
pub struct Field<''a> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn name(self: &Self) -> Option<&str> { /* ... */ }
|
|
```
|
|
The field name found in the
|
|
|
|
- ```rust
|
|
pub fn file_name(self: &Self) -> Option<&str> { /* ... */ }
|
|
```
|
|
The file name found in the
|
|
|
|
- ```rust
|
|
pub fn content_type(self: &Self) -> Option<&str> { /* ... */ }
|
|
```
|
|
Get the [content type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type) of the field.
|
|
|
|
- ```rust
|
|
pub fn headers(self: &Self) -> &HeaderMap { /* ... */ }
|
|
```
|
|
Get a map of headers as [`HeaderMap`].
|
|
|
|
- ```rust
|
|
pub async fn bytes(self: Self) -> Result<Bytes, MultipartError> { /* ... */ }
|
|
```
|
|
Get the full data of the field as [`Bytes`].
|
|
|
|
- ```rust
|
|
pub async fn text(self: Self) -> Result<String, MultipartError> { /* ... */ }
|
|
```
|
|
Get the full field data as text.
|
|
|
|
- ```rust
|
|
pub async fn chunk(self: &mut Self) -> Result<Option<Bytes>, MultipartError> { /* ... */ }
|
|
```
|
|
Stream a chunk of the field data.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Stream**
|
|
- ```rust
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Option<<Self as >::Item>> { /* ... */ }
|
|
```
|
|
|
|
- **StreamExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryStream**
|
|
- ```rust
|
|
fn try_poll_next(self: Pin<&mut S>, cx: &mut Context<''_>) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>> { /* ... */ }
|
|
```
|
|
|
|
- **TryStreamExt**
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `MultipartError`
|
|
|
|
Errors associated with parsing `multipart/form-data` requests.
|
|
|
|
```rust
|
|
pub struct MultipartError {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Enum `MultipartRejection`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection used for [`Multipart`].
|
|
|
|
Contains one variant for each way the [`Multipart`] extractor can fail.
|
|
|
|
```rust
|
|
pub enum MultipartRejection {
|
|
InvalidBoundary(InvalidBoundary),
|
|
}
|
|
```
|
|
|
|
##### Variants
|
|
|
|
###### `InvalidBoundary`
|
|
|
|
Fields:
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `InvalidBoundary` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- ```rust
|
|
fn source(self: &Self) -> Option<&dyn std::error::Error + ''static> { /* ... */ }
|
|
```
|
|
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidBoundary) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `InvalidBoundary`
|
|
|
|
**Attributes:**
|
|
|
|
- `NonExhaustive`
|
|
|
|
Rejection type used if the `boundary` in a `multipart/form-data` is
|
|
missing or invalid.
|
|
|
|
```rust
|
|
pub struct InvalidBoundary;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn body_text(self: &Self) -> String { /* ... */ }
|
|
```
|
|
Get the response body text used for this rejection.
|
|
|
|
- ```rust
|
|
pub fn status(self: &Self) -> http::StatusCode { /* ... */ }
|
|
```
|
|
Get the status code used for this rejection.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Display**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Error**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(inner: InvalidBoundary) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> $crate::response::Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToString**
|
|
- ```rust
|
|
fn to_string(self: &Self) -> String { /* ... */ }
|
|
```
|
|
|
|
- **ToStringFallible**
|
|
- ```rust
|
|
fn try_to_string(self: &Self) -> Result<String, TryReserveError> { /* ... */ }
|
|
```
|
|
[`ToString::to_string`][`alloc::string::ToString::to_string`], but without panic on OOM.
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Re-exports
|
|
|
|
#### Re-export `DefaultBodyLimit`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::DefaultBodyLimit;
|
|
```
|
|
|
|
#### Re-export `FromRef`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::FromRef;
|
|
```
|
|
|
|
#### Re-export `FromRequest`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::FromRequest;
|
|
```
|
|
|
|
#### Re-export `FromRequestParts`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::FromRequestParts;
|
|
```
|
|
|
|
#### Re-export `OptionalFromRequest`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::OptionalFromRequest;
|
|
```
|
|
|
|
#### Re-export `OptionalFromRequestParts`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::OptionalFromRequestParts;
|
|
```
|
|
|
|
#### Re-export `Request`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::extract::Request;
|
|
```
|
|
|
|
#### Re-export `FromRef`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"macros\")]")`
|
|
|
|
```rust
|
|
pub use axum_macros::FromRef;
|
|
```
|
|
|
|
#### Re-export `FromRequest`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"macros\")]")`
|
|
|
|
```rust
|
|
pub use axum_macros::FromRequest;
|
|
```
|
|
|
|
#### Re-export `FromRequestParts`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"macros\")]")`
|
|
|
|
```rust
|
|
pub use axum_macros::FromRequestParts;
|
|
```
|
|
|
|
#### Re-export `NestedPath`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::nested_path::NestedPath;
|
|
```
|
|
|
|
#### Re-export `Path`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::path::Path;
|
|
```
|
|
|
|
#### Re-export `RawPathParams`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::path::RawPathParams;
|
|
```
|
|
|
|
#### Re-export `RawForm`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::raw_form::RawForm;
|
|
```
|
|
|
|
#### Re-export `RawQuery`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::raw_query::RawQuery;
|
|
```
|
|
|
|
#### Re-export `State`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::state::State;
|
|
```
|
|
|
|
#### Re-export `ConnectInfo`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
- `Other("#[<cfg_trace>(feature = \"tokio\")]")`
|
|
|
|
```rust
|
|
pub use self::connect_info::ConnectInfo;
|
|
```
|
|
|
|
#### Re-export `Json`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
- `Other("#[<cfg_trace>(feature = \"json\")]")`
|
|
|
|
```rust
|
|
pub use crate::Json;
|
|
```
|
|
|
|
#### Re-export `Extension`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use crate::Extension;
|
|
```
|
|
|
|
#### Re-export `Form`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"form\")]")`
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use crate::form::Form;
|
|
```
|
|
|
|
#### Re-export `MatchedPath`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"matched-path\")]")`
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::matched_path::MatchedPath;
|
|
```
|
|
|
|
#### Re-export `Multipart`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"multipart\")]")`
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::multipart::Multipart;
|
|
```
|
|
|
|
#### Re-export `Query`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"query\")]")`
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::query::Query;
|
|
```
|
|
|
|
#### Re-export `OriginalUri`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"original-uri\")]")`
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::original_uri::OriginalUri;
|
|
```
|
|
|
|
#### Re-export `WebSocketUpgrade`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"ws\")]")`
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::ws::WebSocketUpgrade;
|
|
```
|
|
|
|
## Module `handler`
|
|
|
|
Async functions that can be used to handle requests.
|
|
|
|
In axum a "handler" is an async function that accepts zero or more
|
|
["extractors"](crate::extract) as arguments and returns something that
|
|
can be converted [into a response](crate::response).
|
|
|
|
Handlers are where your application logic lives and axum applications are built
|
|
by routing between handlers.
|
|
|
|
[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html
|
|
|
|
Some examples of handlers:
|
|
|
|
```rust
|
|
use axum::{body::Bytes, http::StatusCode};
|
|
|
|
// Handler that immediately returns an empty `200 OK` response.
|
|
async fn unit_handler() {}
|
|
|
|
// Handler that immediately returns a `200 OK` response with a plain text
|
|
// body.
|
|
async fn string_handler() -> String {
|
|
"Hello, World!".to_string()
|
|
}
|
|
|
|
// Handler that buffers the request body and returns it.
|
|
//
|
|
// This works because `Bytes` implements `FromRequest`
|
|
// and therefore can be used as an extractor.
|
|
//
|
|
// `String` and `StatusCode` both implement `IntoResponse` and
|
|
// therefore `Result<String, StatusCode>` also implements `IntoResponse`
|
|
async fn echo(body: Bytes) -> Result<String, StatusCode> {
|
|
if let Ok(string) = String::from_utf8(body.to_vec()) {
|
|
Ok(string)
|
|
} else {
|
|
Err(StatusCode::BAD_REQUEST)
|
|
}
|
|
}
|
|
```
|
|
|
|
Instead of a direct `StatusCode`, it makes sense to use intermediate error type
|
|
that can ultimately be converted to `Response`. This allows using `?` operator
|
|
in handlers. See those examples:
|
|
|
|
* [`anyhow-error-response`][anyhow] for generic boxed errors
|
|
* [`error-handling`][error-handling] for application-specific detailed errors
|
|
|
|
[anyhow]: https://github.com/tokio-rs/axum/blob/main/examples/anyhow-error-response/src/main.rs
|
|
[error-handling]: https://github.com/tokio-rs/axum/blob/main/examples/error-handling/src/main.rs
|
|
|
|
## Debugging handler type errors
|
|
|
|
For a function to be used as a handler it must implement the [`Handler`] trait.
|
|
axum provides blanket implementations for functions that:
|
|
|
|
- Are `async fn`s.
|
|
- Take no more than 16 arguments that all implement `Send`.
|
|
- All except the last argument implement [`FromRequestParts`].
|
|
- The last argument implements [`FromRequest`].
|
|
- Returns something that implements [`IntoResponse`].
|
|
- If a closure is used it must implement `Clone + Send` and be
|
|
`'static`.
|
|
- Returns a future that is `Send`. The most common way to accidentally make a
|
|
future `!Send` is to hold a `!Send` type across an await.
|
|
|
|
Unfortunately Rust gives poor error messages if you try to use a function
|
|
that doesn't quite match what's required by [`Handler`].
|
|
|
|
You might get an error like this:
|
|
|
|
```not_rust
|
|
error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied
|
|
--> src/main.rs:13:44
|
|
|
|
|
13 | let app = Router::new().route("/", get(handler));
|
|
| ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`
|
|
|
|
|
::: axum/src/handler/mod.rs:116:8
|
|
|
|
|
116 | H: Handler<T, B>,
|
|
| ------------- required by this bound in `axum::routing::get`
|
|
```
|
|
|
|
This error doesn't tell you _why_ your function doesn't implement
|
|
[`Handler`]. It's possible to improve the error with the [`debug_handler`]
|
|
proc-macro from the [axum-macros] crate.
|
|
|
|
[axum-macros]: https://docs.rs/axum-macros
|
|
[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html
|
|
|
|
```rust
|
|
pub mod handler { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `future`
|
|
|
|
Handler future types.
|
|
|
|
```rust
|
|
pub mod future { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `IntoServiceFuture`
|
|
|
|
The response future for [`IntoService`](super::IntoService).
|
|
|
|
```rust
|
|
pub struct IntoServiceFuture<F> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Future**
|
|
- ```rust
|
|
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<''_>) -> std::task::Poll<<Self as >::Output> { /* ... */ }
|
|
```
|
|
|
|
- **FutureExt**
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoFuture**
|
|
- ```rust
|
|
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryFuture**
|
|
- ```rust
|
|
fn try_poll(self: Pin<&mut F>, cx: &mut Context<''_>) -> Poll<<F as Future>::Output> { /* ... */ }
|
|
```
|
|
|
|
- **TryFutureExt**
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `LayeredFuture`
|
|
|
|
The response future for [`Layered`](super::Layered).
|
|
|
|
```rust
|
|
pub struct LayeredFuture<S> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Future**
|
|
- ```rust
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<''_>) -> std::task::Poll<<Self as >::Output> { /* ... */ }
|
|
```
|
|
|
|
- **FutureExt**
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoFuture**
|
|
- ```rust
|
|
fn into_future(self: Self) -> <F as IntoFuture>::IntoFuture { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Types
|
|
|
|
#### Struct `Layered`
|
|
|
|
A [`Service`] created from a [`Handler`] by applying a Tower middleware.
|
|
|
|
Created with [`Handler::layer`]. See that method for more details.
|
|
|
|
```rust
|
|
pub struct Layered<L, H, T, S> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Handler**
|
|
- ```rust
|
|
fn call(self: Self, req: Request, state: S) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **HandlerWithoutStateExt**
|
|
- ```rust
|
|
fn into_service(self: Self) -> HandlerService<H, T, ()> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<HandlerService<H, T, ()>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Traits
|
|
|
|
#### Trait `Handler`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[diagnostic::on_unimplemented(note =\n\"Consider using `#[axum::debug_handler]` to improve the error message\")]")`
|
|
|
|
Trait for async functions that can be used to handle requests.
|
|
|
|
You shouldn't need to depend on this trait directly. It is automatically
|
|
implemented to closures of the right types.
|
|
|
|
See the [module docs](crate::handler) for more details.
|
|
|
|
# Converting `Handler`s into [`Service`]s
|
|
|
|
To convert `Handler`s into [`Service`]s you have to call either
|
|
[`HandlerWithoutStateExt::into_service`] or [`Handler::with_state`]:
|
|
|
|
```
|
|
use tower::Service;
|
|
use axum::{
|
|
extract::{State, Request},
|
|
body::Body,
|
|
handler::{HandlerWithoutStateExt, Handler},
|
|
};
|
|
|
|
// this handler doesn't require any state
|
|
async fn one() {}
|
|
// so it can be converted to a service with `HandlerWithoutStateExt::into_service`
|
|
assert_service(one.into_service());
|
|
|
|
// this handler requires state
|
|
async fn two(_: State<String>) {}
|
|
// so we have to provide it
|
|
let handler_with_state = two.with_state(String::new());
|
|
// which gives us a `Service`
|
|
assert_service(handler_with_state);
|
|
|
|
// helper to check that a value implements `Service`
|
|
fn assert_service<S>(service: S)
|
|
where
|
|
S: Service<Request>,
|
|
{}
|
|
```
|
|
## Debugging handler type errors
|
|
|
|
For a function to be used as a handler it must implement the [`Handler`] trait.
|
|
axum provides blanket implementations for functions that:
|
|
|
|
- Are `async fn`s.
|
|
- Take no more than 16 arguments that all implement `Send`.
|
|
- All except the last argument implement [`FromRequestParts`].
|
|
- The last argument implements [`FromRequest`].
|
|
- Returns something that implements [`IntoResponse`].
|
|
- If a closure is used it must implement `Clone + Send` and be
|
|
`'static`.
|
|
- Returns a future that is `Send`. The most common way to accidentally make a
|
|
future `!Send` is to hold a `!Send` type across an await.
|
|
|
|
Unfortunately Rust gives poor error messages if you try to use a function
|
|
that doesn't quite match what's required by [`Handler`].
|
|
|
|
You might get an error like this:
|
|
|
|
```not_rust
|
|
error[E0277]: the trait bound `fn(bool) -> impl Future {handler}: Handler<_, _>` is not satisfied
|
|
--> src/main.rs:13:44
|
|
|
|
|
13 | let app = Router::new().route("/", get(handler));
|
|
| ^^^^^^^ the trait `Handler<_, _>` is not implemented for `fn(bool) -> impl Future {handler}`
|
|
|
|
|
::: axum/src/handler/mod.rs:116:8
|
|
|
|
|
116 | H: Handler<T, B>,
|
|
| ------------- required by this bound in `axum::routing::get`
|
|
```
|
|
|
|
This error doesn't tell you _why_ your function doesn't implement
|
|
[`Handler`]. It's possible to improve the error with the [`debug_handler`]
|
|
proc-macro from the [axum-macros] crate.
|
|
|
|
[axum-macros]: https://docs.rs/axum-macros
|
|
[`debug_handler`]: https://docs.rs/axum-macros/latest/axum_macros/attr.debug_handler.html
|
|
|
|
# Handlers that aren't functions
|
|
|
|
The `Handler` trait is also implemented for `T: IntoResponse`. That allows easily returning
|
|
fixed data for routes:
|
|
|
|
```
|
|
use axum::{
|
|
Router,
|
|
routing::{get, post},
|
|
Json,
|
|
http::StatusCode,
|
|
};
|
|
use serde_json::json;
|
|
|
|
let app = Router::new()
|
|
// respond with a fixed string
|
|
.route("/", get("Hello, World!"))
|
|
// or return some mock data
|
|
.route("/users", post((
|
|
StatusCode::CREATED,
|
|
Json(json!({ "id": 1, "username": "alice" })),
|
|
)));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# About type parameter `T`
|
|
|
|
**Generally you shouldn't need to worry about `T`**; when calling methods such as
|
|
[`post`](crate::routing::method_routing::post) it will be automatically inferred and this is
|
|
the intended way for this parameter to be provided in application code.
|
|
|
|
If you are implementing your own methods that accept implementations of `Handler` as
|
|
arguments, then the following may be useful:
|
|
|
|
The type parameter `T` is a workaround for trait coherence rules, allowing us to
|
|
write blanket implementations of `Handler` over many types of handler functions
|
|
with different numbers of arguments, without the compiler forbidding us from doing
|
|
so because one type `F` can in theory implement both `Fn(A) -> X` and `Fn(A, B) -> Y`.
|
|
`T` is a placeholder taking on a representation of the parameters of the handler function,
|
|
as well as other similar 'coherence rule workaround' discriminators,
|
|
allowing us to select one function signature to use as a `Handler`.
|
|
|
|
```rust
|
|
pub trait Handler<T, S>: Clone + Send + Sync + Sized + ''static {
|
|
/* Associated items */
|
|
}
|
|
```
|
|
|
|
> This trait is not object-safe and cannot be used in dynamic trait objects.
|
|
|
|
##### Required Items
|
|
|
|
###### Associated Types
|
|
|
|
- `Future`: The type of future calling this handler returns.
|
|
|
|
###### Required Methods
|
|
|
|
- `call`: Call the handler with the given request.
|
|
|
|
##### Provided Methods
|
|
|
|
- ```rust
|
|
fn layer<L>(self: Self, layer: L) -> Layered<L, Self, T, S>
|
|
where
|
|
L: Layer<HandlerService<Self, T, S>> + Clone,
|
|
<L as >::Service: Service<Request> { /* ... */ }
|
|
```
|
|
Apply a [`tower::Layer`] to the handler.
|
|
|
|
- ```rust
|
|
fn with_state(self: Self, state: S) -> HandlerService<Self, T, S> { /* ... */ }
|
|
```
|
|
Convert the handler into a [`Service`] by providing the state
|
|
|
|
##### Implementations
|
|
|
|
This trait is implemented for the following types:
|
|
|
|
- `F` with <F, Fut, Res, S>
|
|
- `F` with <F, Fut, S, Res, M, T1>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>
|
|
- `F` with <F, Fut, S, Res, M, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>
|
|
- `Layered<L, H, T, S>` with <H, S, T, L>
|
|
- `MethodRouter<S>` with <S>
|
|
|
|
#### Trait `HandlerWithoutStateExt`
|
|
|
|
Extension trait for [`Handler`]s that don't have state.
|
|
|
|
This provides convenience methods to convert the [`Handler`] into a [`Service`] or [`MakeService`].
|
|
|
|
[`MakeService`]: tower::make::MakeService
|
|
|
|
```rust
|
|
pub trait HandlerWithoutStateExt<T>: Handler<T, ()> {
|
|
/* Associated items */
|
|
}
|
|
```
|
|
|
|
> This trait is not object-safe and cannot be used in dynamic trait objects.
|
|
|
|
##### Required Items
|
|
|
|
###### Required Methods
|
|
|
|
- `into_service`: Convert the handler into a [`Service`] and no state.
|
|
- `into_make_service`: Convert the handler into a [`MakeService`] and no state.
|
|
- `into_make_service_with_connect_info`: Convert the handler into a [`MakeService`] which stores information
|
|
|
|
##### Implementations
|
|
|
|
This trait is implemented for the following types:
|
|
|
|
- `H` with <H, T>
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `HandlerService`
|
|
|
|
```rust
|
|
pub use self::service::HandlerService;
|
|
```
|
|
|
|
## Module `middleware`
|
|
|
|
Utilities for writing middleware
|
|
|
|
# Intro
|
|
|
|
axum is unique in that it doesn't have its own bespoke middleware system and
|
|
instead integrates with [`tower`]. This means the ecosystem of [`tower`] and
|
|
[`tower-http`] middleware all work with axum.
|
|
|
|
While it's not necessary to fully understand tower to write or use middleware
|
|
with axum, having at least a basic understanding of tower's concepts is
|
|
recommended. See [tower's guides][tower-guides] for a general introduction.
|
|
Reading the documentation for [`tower::ServiceBuilder`] is also recommended.
|
|
|
|
# Applying middleware
|
|
|
|
axum allows you to add middleware just about anywhere
|
|
|
|
- To entire routers with [`Router::layer`] and [`Router::route_layer`].
|
|
- To method routers with [`MethodRouter::layer`] and [`MethodRouter::route_layer`].
|
|
- To individual handlers with [`Handler::layer`].
|
|
|
|
## Applying multiple middleware
|
|
|
|
It's recommended to use [`tower::ServiceBuilder`] to apply multiple middleware at
|
|
once, instead of calling `layer` (or `route_layer`) repeatedly:
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::get,
|
|
Extension,
|
|
Router,
|
|
};
|
|
use tower_http::{trace::TraceLayer};
|
|
use tower::ServiceBuilder;
|
|
|
|
async fn handler() {}
|
|
|
|
#[derive(Clone)]
|
|
struct State {}
|
|
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
.layer(TraceLayer::new_for_http())
|
|
.layer(Extension(State {}))
|
|
);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
# Commonly used middleware
|
|
|
|
Some commonly used middleware are:
|
|
|
|
- [`TraceLayer`](tower_http::trace) for high level tracing/logging.
|
|
- [`CorsLayer`](tower_http::cors) for handling CORS.
|
|
- [`CompressionLayer`](tower_http::compression) for automatic compression of responses.
|
|
- [`RequestIdLayer`](tower_http::request_id) and
|
|
[`PropagateRequestIdLayer`](tower_http::request_id) set and propagate request
|
|
ids.
|
|
- [`TimeoutLayer`](tower_http::timeout::TimeoutLayer) for timeouts.
|
|
|
|
# Ordering
|
|
|
|
When you add middleware with [`Router::layer`] (or similar) all previously added
|
|
routes will be wrapped in the middleware. Generally speaking, this results in
|
|
middleware being executed from bottom to top.
|
|
|
|
So if you do this:
|
|
|
|
```rust
|
|
use axum::{routing::get, Router};
|
|
|
|
async fn handler() {}
|
|
|
|
# let layer_one = axum::Extension(());
|
|
# let layer_two = axum::Extension(());
|
|
# let layer_three = axum::Extension(());
|
|
#
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.layer(layer_one)
|
|
.layer(layer_two)
|
|
.layer(layer_three);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
Think of the middleware as being layered like an onion where each new layer
|
|
wraps all previous layers:
|
|
|
|
```not_rust
|
|
requests
|
|
|
|
|
v
|
|
+----- layer_three -----+
|
|
| +---- layer_two ----+ |
|
|
| | +-- layer_one --+ | |
|
|
| | | | | |
|
|
| | | handler | | |
|
|
| | | | | |
|
|
| | +-- layer_one --+ | |
|
|
| +---- layer_two ----+ |
|
|
+----- layer_three -----+
|
|
|
|
|
v
|
|
responses
|
|
```
|
|
|
|
That is:
|
|
|
|
- First `layer_three` receives the request
|
|
- It then does its thing and passes the request onto `layer_two`
|
|
- Which passes the request onto `layer_one`
|
|
- Which passes the request onto `handler` where a response is produced
|
|
- That response is then passed to `layer_one`
|
|
- Then to `layer_two`
|
|
- And finally to `layer_three` where it's returned out of your app
|
|
|
|
It's a little more complicated in practice because any middleware is free to
|
|
return early and not call the next layer, for example if a request cannot be
|
|
authorized, but it's a useful mental model to have.
|
|
|
|
As previously mentioned it's recommended to add multiple middleware using
|
|
`tower::ServiceBuilder`, however this impacts ordering:
|
|
|
|
```rust
|
|
use tower::ServiceBuilder;
|
|
use axum::{routing::get, Router};
|
|
|
|
async fn handler() {}
|
|
|
|
# let layer_one = axum::Extension(());
|
|
# let layer_two = axum::Extension(());
|
|
# let layer_three = axum::Extension(());
|
|
#
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
.layer(layer_one)
|
|
.layer(layer_two)
|
|
.layer(layer_three),
|
|
);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
`ServiceBuilder` works by composing all layers into one such that they run top
|
|
to bottom. So with the previous code `layer_one` would receive the request
|
|
first, then `layer_two`, then `layer_three`, then `handler`, and then the
|
|
response would bubble back up through `layer_three`, then `layer_two`, and
|
|
finally `layer_one`.
|
|
|
|
Executing middleware top to bottom is generally easier to understand and follow
|
|
mentally which is one of the reasons `ServiceBuilder` is recommended.
|
|
|
|
# Writing middleware
|
|
|
|
axum offers many ways of writing middleware, at different levels of abstraction
|
|
and with different pros and cons.
|
|
|
|
## `axum::middleware::from_fn`
|
|
|
|
Use [`axum::middleware::from_fn`] to write your middleware when:
|
|
|
|
- You're not comfortable with implementing your own futures and would rather use
|
|
the familiar `async`/`await` syntax.
|
|
- You don't intend to publish your middleware as a crate for others to use.
|
|
Middleware written like this are only compatible with axum.
|
|
|
|
## `axum::middleware::from_extractor`
|
|
|
|
Use [`axum::middleware::from_extractor`] to write your middleware when:
|
|
|
|
- You have a type that you sometimes want to use as an extractor and sometimes
|
|
as a middleware. If you only need your type as a middleware prefer
|
|
[`middleware::from_fn`].
|
|
|
|
## tower's combinators
|
|
|
|
tower has several utility combinators that can be used to perform simple
|
|
modifications to requests or responses. The most commonly used ones are
|
|
|
|
- [`ServiceBuilder::map_request`]
|
|
- [`ServiceBuilder::map_response`]
|
|
- [`ServiceBuilder::then`]
|
|
- [`ServiceBuilder::and_then`]
|
|
|
|
You should use these when
|
|
|
|
- You want to perform a small ad hoc operation, such as adding a header.
|
|
- You don't intend to publish your middleware as a crate for others to use.
|
|
|
|
## `tower::Service` and `Pin<Box<dyn Future>>`
|
|
|
|
For maximum control (and a more low level API) you can write your own middleware
|
|
by implementing [`tower::Service`]:
|
|
|
|
Use [`tower::Service`] with `Pin<Box<dyn Future>>` to write your middleware when:
|
|
|
|
- Your middleware needs to be configurable for example via builder methods on
|
|
your [`tower::Layer`] such as [`tower_http::trace::TraceLayer`].
|
|
- You do intend to publish your middleware as a crate for others to use.
|
|
- You're not comfortable with implementing your own futures.
|
|
|
|
A decent template for such a middleware could be:
|
|
|
|
```rust
|
|
use axum::{
|
|
response::Response,
|
|
body::Body,
|
|
extract::Request,
|
|
};
|
|
use futures_util::future::BoxFuture;
|
|
use tower::{Service, Layer};
|
|
use std::task::{Context, Poll};
|
|
|
|
#[derive(Clone)]
|
|
struct MyLayer;
|
|
|
|
impl<S> Layer<S> for MyLayer {
|
|
type Service = MyMiddleware<S>;
|
|
|
|
fn layer(&self, inner: S) -> Self::Service {
|
|
MyMiddleware { inner }
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct MyMiddleware<S> {
|
|
inner: S,
|
|
}
|
|
|
|
impl<S> Service<Request> for MyMiddleware<S>
|
|
where
|
|
S: Service<Request, Response = Response> + Send + 'static,
|
|
S::Future: Send + 'static,
|
|
{
|
|
type Response = S::Response;
|
|
type Error = S::Error;
|
|
// `BoxFuture` is a type alias for `Pin<Box<dyn Future + Send + 'a>>`
|
|
type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>;
|
|
|
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
self.inner.poll_ready(cx)
|
|
}
|
|
|
|
fn call(&mut self, request: Request) -> Self::Future {
|
|
let future = self.inner.call(request);
|
|
Box::pin(async move {
|
|
let response: Response = future.await?;
|
|
Ok(response)
|
|
})
|
|
}
|
|
}
|
|
```
|
|
|
|
Note that your error type being defined as `S::Error` means that your middleware typically _returns no errors_. As a principle always try to return a response and try not to bail out with a custom error type. For example, if a 3rd party library you are using inside your new middleware returns its own specialized error type, try to convert it to some reasonable response and return `Ok` with that response.
|
|
|
|
If you choose to implement a custom error type such as `type Error = BoxError` (a boxed opaque error), or any other error type that is not `Infallible`, you must use a `HandleErrorLayer`, here is an example using a `ServiceBuilder`:
|
|
|
|
```ignore
|
|
ServiceBuilder::new()
|
|
.layer(HandleErrorLayer::new(|_: BoxError| async {
|
|
// because axum uses infallible errors, you must handle your custom error type from your middleware here
|
|
StatusCode::BAD_REQUEST
|
|
}))
|
|
.layer(
|
|
// <your actual layer which DOES return an error>
|
|
);
|
|
```
|
|
|
|
## `tower::Service` and custom futures
|
|
|
|
If you're comfortable implementing your own futures (or want to learn it) and
|
|
need as much control as possible then using `tower::Service` without boxed
|
|
futures is the way to go.
|
|
|
|
Use [`tower::Service`] with manual futures to write your middleware when:
|
|
|
|
- You want your middleware to have the lowest possible overhead.
|
|
- Your middleware needs to be configurable for example via builder methods on
|
|
your [`tower::Layer`] such as [`tower_http::trace::TraceLayer`].
|
|
- You do intend to publish your middleware as a crate for others to use, perhaps
|
|
as part of tower-http.
|
|
- You're comfortable with implementing your own futures, or want to learn how
|
|
the lower levels of async Rust works.
|
|
|
|
tower's ["Building a middleware from scratch"][tower-from-scratch-guide]
|
|
guide is a good place to learn how to do this.
|
|
|
|
# Error handling for middleware
|
|
|
|
axum's error handling model requires handlers to always return a response.
|
|
However middleware is one possible way to introduce errors into an application.
|
|
If hyper receives an error the connection will be closed without sending a
|
|
response. Thus axum requires those errors to be handled gracefully:
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::get,
|
|
error_handling::HandleErrorLayer,
|
|
http::StatusCode,
|
|
BoxError,
|
|
Router,
|
|
};
|
|
use tower::{ServiceBuilder, timeout::TimeoutLayer};
|
|
use std::time::Duration;
|
|
|
|
async fn handler() {}
|
|
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
// this middleware goes above `TimeoutLayer` because it will receive
|
|
// errors returned by `TimeoutLayer`
|
|
.layer(HandleErrorLayer::new(|_: BoxError| async {
|
|
StatusCode::REQUEST_TIMEOUT
|
|
}))
|
|
.layer(TimeoutLayer::new(Duration::from_secs(10)))
|
|
);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
See [`error_handling`](crate::error_handling) for more details on axum's error
|
|
handling model.
|
|
|
|
# Routing to services/middleware and backpressure
|
|
|
|
Generally routing to one of multiple services and backpressure doesn't mix
|
|
well. Ideally you would want ensure a service is ready to receive a request
|
|
before calling it. However, in order to know which service to call, you need
|
|
the request...
|
|
|
|
One approach is to not consider the router service itself ready until all
|
|
destination services are ready. That is the approach used by
|
|
[`tower::steer::Steer`].
|
|
|
|
Another approach is to always consider all services ready (always return
|
|
`Poll::Ready(Ok(()))`) from `Service::poll_ready` and then actually drive
|
|
readiness inside the response future returned by `Service::call`. This works
|
|
well when your services don't care about backpressure and are always ready
|
|
anyway.
|
|
|
|
axum expects that all services used in your app won't care about
|
|
backpressure and so it uses the latter strategy. However that means you
|
|
should avoid routing to a service (or using a middleware) that _does_ care
|
|
about backpressure. At the very least you should [load shed][tower::load_shed]
|
|
so requests are dropped quickly and don't keep piling up.
|
|
|
|
It also means that if `poll_ready` returns an error then that error will be
|
|
returned in the response future from `call` and _not_ from `poll_ready`. In
|
|
that case, the underlying service will _not_ be discarded and will continue
|
|
to be used for future requests. Services that expect to be discarded if
|
|
`poll_ready` fails should _not_ be used with axum.
|
|
|
|
One possible approach is to only apply backpressure sensitive middleware
|
|
around your entire app. This is possible because axum applications are
|
|
themselves services:
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use tower::ServiceBuilder;
|
|
# let some_backpressure_sensitive_middleware =
|
|
# tower::layer::util::Identity::new();
|
|
|
|
async fn handler() { /* ... */ }
|
|
|
|
let app = Router::new().route("/", get(handler));
|
|
|
|
let app = ServiceBuilder::new()
|
|
.layer(some_backpressure_sensitive_middleware)
|
|
.service(app);
|
|
# let _: Router = app;
|
|
```
|
|
|
|
However when applying middleware around your whole application in this way
|
|
you have to take care that errors are still being handled appropriately.
|
|
|
|
Also note that handlers created from async functions don't care about
|
|
backpressure and are always ready. So if you're not using any Tower
|
|
middleware you don't have to worry about any of this.
|
|
|
|
# Accessing state in middleware
|
|
|
|
How to make state available to middleware depends on how the middleware is
|
|
written.
|
|
|
|
## Accessing state in `axum::middleware::from_fn`
|
|
|
|
Use [`axum::middleware::from_fn_with_state`](crate::middleware::from_fn_with_state).
|
|
|
|
## Accessing state in custom `tower::Layer`s
|
|
|
|
```rust
|
|
use axum::{
|
|
Router,
|
|
routing::get,
|
|
middleware::{self, Next},
|
|
response::Response,
|
|
extract::{State, Request},
|
|
};
|
|
use tower::{Layer, Service};
|
|
use std::task::{Context, Poll};
|
|
|
|
#[derive(Clone)]
|
|
struct AppState {}
|
|
|
|
#[derive(Clone)]
|
|
struct MyLayer {
|
|
state: AppState,
|
|
}
|
|
|
|
impl<S> Layer<S> for MyLayer {
|
|
type Service = MyService<S>;
|
|
|
|
fn layer(&self, inner: S) -> Self::Service {
|
|
MyService {
|
|
inner,
|
|
state: self.state.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct MyService<S> {
|
|
inner: S,
|
|
state: AppState,
|
|
}
|
|
|
|
impl<S, B> Service<Request<B>> for MyService<S>
|
|
where
|
|
S: Service<Request<B>>,
|
|
{
|
|
type Response = S::Response;
|
|
type Error = S::Error;
|
|
type Future = S::Future;
|
|
|
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
|
self.inner.poll_ready(cx)
|
|
}
|
|
|
|
fn call(&mut self, req: Request<B>) -> Self::Future {
|
|
// Do something with `self.state`.
|
|
//
|
|
// See `axum::RequestExt` for how to run extractors directly from
|
|
// a `Request`.
|
|
|
|
self.inner.call(req)
|
|
}
|
|
}
|
|
|
|
async fn handler(_: State<AppState>) {}
|
|
|
|
let state = AppState {};
|
|
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.layer(MyLayer { state: state.clone() })
|
|
.with_state(state);
|
|
# let _: axum::Router = app;
|
|
```
|
|
|
|
# Passing state from middleware to handlers
|
|
|
|
State can be passed from middleware to handlers using [request extensions]:
|
|
|
|
```rust
|
|
use axum::{
|
|
Router,
|
|
http::StatusCode,
|
|
routing::get,
|
|
response::{IntoResponse, Response},
|
|
middleware::{self, Next},
|
|
extract::{Request, Extension},
|
|
};
|
|
|
|
#[derive(Clone)]
|
|
struct CurrentUser { /* ... */ }
|
|
|
|
async fn auth(mut req: Request, next: Next) -> Result<Response, StatusCode> {
|
|
let auth_header = req.headers()
|
|
.get(http::header::AUTHORIZATION)
|
|
.and_then(|header| header.to_str().ok());
|
|
|
|
let auth_header = if let Some(auth_header) = auth_header {
|
|
auth_header
|
|
} else {
|
|
return Err(StatusCode::UNAUTHORIZED);
|
|
};
|
|
|
|
if let Some(current_user) = authorize_current_user(auth_header).await {
|
|
// insert the current user into a request extension so the handler can
|
|
// extract it
|
|
req.extensions_mut().insert(current_user);
|
|
Ok(next.run(req).await)
|
|
} else {
|
|
Err(StatusCode::UNAUTHORIZED)
|
|
}
|
|
}
|
|
|
|
async fn authorize_current_user(auth_token: &str) -> Option<CurrentUser> {
|
|
// ...
|
|
# unimplemented!()
|
|
}
|
|
|
|
async fn handler(
|
|
// extract the current user, set by the middleware
|
|
Extension(current_user): Extension<CurrentUser>,
|
|
) {
|
|
// ...
|
|
}
|
|
|
|
let app = Router::new()
|
|
.route("/", get(handler))
|
|
.route_layer(middleware::from_fn(auth));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
[Response extensions] can also be used but note that request extensions are not
|
|
automatically moved to response extensions. You need to manually do that for the
|
|
extensions you need.
|
|
|
|
# Rewriting request URI in middleware
|
|
|
|
Middleware added with [`Router::layer`] will run after routing. That means it
|
|
cannot be used to run middleware that rewrites the request URI. By the time the
|
|
middleware runs the routing is already done.
|
|
|
|
The workaround is to wrap the middleware around the entire `Router` (this works
|
|
because `Router` implements [`Service`]):
|
|
|
|
```rust
|
|
use tower::Layer;
|
|
use axum::{
|
|
Router,
|
|
ServiceExt, // for `into_make_service`
|
|
response::Response,
|
|
middleware::Next,
|
|
extract::Request,
|
|
};
|
|
|
|
fn rewrite_request_uri<B>(req: Request<B>) -> Request<B> {
|
|
// ...
|
|
# req
|
|
}
|
|
|
|
// this can be any `tower::Layer`
|
|
let middleware = tower::util::MapRequestLayer::new(rewrite_request_uri);
|
|
|
|
let app = Router::new();
|
|
|
|
// apply the layer around the whole `Router`
|
|
// this way the middleware will run before `Router` receives the request
|
|
let app_with_middleware = middleware.layer(app);
|
|
|
|
# async {
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
|
axum::serve(listener, app_with_middleware.into_make_service()).await.unwrap();
|
|
# };
|
|
```
|
|
|
|
[`tower`]: https://crates.io/crates/tower
|
|
[`tower-http`]: https://crates.io/crates/tower-http
|
|
[tower-guides]: https://github.com/tower-rs/tower/tree/master/guides
|
|
[`axum::middleware::from_fn`]: fn@crate::middleware::from_fn
|
|
[`middleware::from_fn`]: fn@crate::middleware::from_fn
|
|
[tower-from-scratch-guide]: https://github.com/tower-rs/tower/blob/master/guides/building-a-middleware-from-scratch.md
|
|
[`ServiceBuilder::map_request`]: tower::ServiceBuilder::map_request
|
|
[`ServiceBuilder::map_response`]: tower::ServiceBuilder::map_response
|
|
[`ServiceBuilder::then`]: tower::ServiceBuilder::then
|
|
[`ServiceBuilder::and_then`]: tower::ServiceBuilder::and_then
|
|
[`axum::middleware::from_extractor`]: fn@crate::middleware::from_extractor
|
|
[`Handler::layer`]: crate::handler::Handler::layer
|
|
[`Router::layer`]: crate::routing::Router::layer
|
|
[`MethodRouter::layer`]: crate::routing::MethodRouter::layer
|
|
[`Router::route_layer`]: crate::routing::Router::route_layer
|
|
[`MethodRouter::route_layer`]: crate::routing::MethodRouter::route_layer
|
|
[request extensions]: https://docs.rs/http/latest/http/request/struct.Request.html#method.extensions
|
|
[Response extensions]: https://docs.rs/http/latest/http/response/struct.Response.html#method.extensions
|
|
[`State`]: crate::extract::State
|
|
[`Service`]: tower::Service
|
|
|
|
```rust
|
|
pub mod middleware { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `future`
|
|
|
|
Future types.
|
|
|
|
```rust
|
|
pub mod future { /* ... */ }
|
|
```
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `ResponseFuture`
|
|
|
|
```rust
|
|
pub use super::from_extractor::ResponseFuture as FromExtractorResponseFuture;
|
|
```
|
|
|
|
#### Re-export `ResponseFuture`
|
|
|
|
```rust
|
|
pub use super::from_fn::ResponseFuture as FromFnResponseFuture;
|
|
```
|
|
|
|
#### Re-export `ResponseFuture`
|
|
|
|
```rust
|
|
pub use super::map_request::ResponseFuture as MapRequestResponseFuture;
|
|
```
|
|
|
|
#### Re-export `ResponseFuture`
|
|
|
|
```rust
|
|
pub use super::map_response::ResponseFuture as MapResponseResponseFuture;
|
|
```
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `from_extractor`
|
|
|
|
```rust
|
|
pub use self::from_extractor::from_extractor;
|
|
```
|
|
|
|
#### Re-export `from_extractor_with_state`
|
|
|
|
```rust
|
|
pub use self::from_extractor::from_extractor_with_state;
|
|
```
|
|
|
|
#### Re-export `FromExtractor`
|
|
|
|
```rust
|
|
pub use self::from_extractor::FromExtractor;
|
|
```
|
|
|
|
#### Re-export `FromExtractorLayer`
|
|
|
|
```rust
|
|
pub use self::from_extractor::FromExtractorLayer;
|
|
```
|
|
|
|
#### Re-export `from_fn`
|
|
|
|
```rust
|
|
pub use self::from_fn::from_fn;
|
|
```
|
|
|
|
#### Re-export `from_fn_with_state`
|
|
|
|
```rust
|
|
pub use self::from_fn::from_fn_with_state;
|
|
```
|
|
|
|
#### Re-export `FromFn`
|
|
|
|
```rust
|
|
pub use self::from_fn::FromFn;
|
|
```
|
|
|
|
#### Re-export `FromFnLayer`
|
|
|
|
```rust
|
|
pub use self::from_fn::FromFnLayer;
|
|
```
|
|
|
|
#### Re-export `Next`
|
|
|
|
```rust
|
|
pub use self::from_fn::Next;
|
|
```
|
|
|
|
#### Re-export `map_request`
|
|
|
|
```rust
|
|
pub use self::map_request::map_request;
|
|
```
|
|
|
|
#### Re-export `map_request_with_state`
|
|
|
|
```rust
|
|
pub use self::map_request::map_request_with_state;
|
|
```
|
|
|
|
#### Re-export `IntoMapRequestResult`
|
|
|
|
```rust
|
|
pub use self::map_request::IntoMapRequestResult;
|
|
```
|
|
|
|
#### Re-export `MapRequest`
|
|
|
|
```rust
|
|
pub use self::map_request::MapRequest;
|
|
```
|
|
|
|
#### Re-export `MapRequestLayer`
|
|
|
|
```rust
|
|
pub use self::map_request::MapRequestLayer;
|
|
```
|
|
|
|
#### Re-export `map_response`
|
|
|
|
```rust
|
|
pub use self::map_response::map_response;
|
|
```
|
|
|
|
#### Re-export `map_response_with_state`
|
|
|
|
```rust
|
|
pub use self::map_response::map_response_with_state;
|
|
```
|
|
|
|
#### Re-export `MapResponse`
|
|
|
|
```rust
|
|
pub use self::map_response::MapResponse;
|
|
```
|
|
|
|
#### Re-export `MapResponseLayer`
|
|
|
|
```rust
|
|
pub use self::map_response::MapResponseLayer;
|
|
```
|
|
|
|
#### Re-export `ResponseAxumBody`
|
|
|
|
```rust
|
|
pub use self::response_axum_body::ResponseAxumBody;
|
|
```
|
|
|
|
#### Re-export `ResponseAxumBodyFuture`
|
|
|
|
```rust
|
|
pub use self::response_axum_body::ResponseAxumBodyFuture;
|
|
```
|
|
|
|
#### Re-export `ResponseAxumBodyLayer`
|
|
|
|
```rust
|
|
pub use self::response_axum_body::ResponseAxumBodyLayer;
|
|
```
|
|
|
|
#### Re-export `AddExtension`
|
|
|
|
```rust
|
|
pub use crate::extension::AddExtension;
|
|
```
|
|
|
|
## Module `response`
|
|
|
|
Types and traits for generating responses.
|
|
|
|
# Building responses
|
|
|
|
Anything that implements [`IntoResponse`] can be returned from a handler. axum
|
|
provides implementations for common types:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
Json,
|
|
response::{Html, IntoResponse},
|
|
http::{StatusCode, Uri, header::{self, HeaderMap, HeaderName}},
|
|
};
|
|
|
|
// `()` gives an empty response
|
|
async fn empty() {}
|
|
|
|
// String will get a `text/plain; charset=utf-8` content-type
|
|
async fn plain_text(uri: Uri) -> String {
|
|
format!("Hi from {}", uri.path())
|
|
}
|
|
|
|
// Bytes will get a `application/octet-stream` content-type
|
|
async fn bytes() -> Vec<u8> {
|
|
vec![1, 2, 3, 4]
|
|
}
|
|
|
|
// `Json` will get a `application/json` content-type and work with anything that
|
|
// implements `serde::Serialize`
|
|
async fn json() -> Json<Vec<String>> {
|
|
Json(vec!["foo".to_owned(), "bar".to_owned()])
|
|
}
|
|
|
|
// `Html` will get a `text/html` content-type
|
|
async fn html() -> Html<&'static str> {
|
|
Html("<p>Hello, World!</p>")
|
|
}
|
|
|
|
// `StatusCode` gives an empty response with that status code
|
|
async fn status() -> StatusCode {
|
|
StatusCode::NOT_FOUND
|
|
}
|
|
|
|
// `HeaderMap` gives an empty response with some headers
|
|
async fn headers() -> HeaderMap {
|
|
let mut headers = HeaderMap::new();
|
|
headers.insert(header::SERVER, "axum".parse().unwrap());
|
|
headers
|
|
}
|
|
|
|
// An array of tuples also gives headers
|
|
async fn array_headers() -> [(HeaderName, &'static str); 2] {
|
|
[
|
|
(header::SERVER, "axum"),
|
|
(header::CONTENT_TYPE, "text/plain")
|
|
]
|
|
}
|
|
|
|
// Use `impl IntoResponse` to avoid writing the whole type
|
|
async fn impl_trait() -> impl IntoResponse {
|
|
[
|
|
(header::SERVER, "axum"),
|
|
(header::CONTENT_TYPE, "text/plain")
|
|
]
|
|
}
|
|
```
|
|
|
|
Additionally you can return tuples to build more complex responses from
|
|
individual parts.
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
Json,
|
|
response::IntoResponse,
|
|
http::{StatusCode, HeaderMap, Uri, header},
|
|
extract::Extension,
|
|
};
|
|
|
|
// `(StatusCode, impl IntoResponse)` will override the status code of the response
|
|
async fn with_status(uri: Uri) -> (StatusCode, String) {
|
|
(StatusCode::NOT_FOUND, format!("Not Found: {}", uri.path()))
|
|
}
|
|
|
|
// Use `impl IntoResponse` to avoid having to type the whole type
|
|
async fn impl_trait(uri: Uri) -> impl IntoResponse {
|
|
(StatusCode::NOT_FOUND, format!("Not Found: {}", uri.path()))
|
|
}
|
|
|
|
// `(HeaderMap, impl IntoResponse)` to add additional headers
|
|
async fn with_headers() -> impl IntoResponse {
|
|
let mut headers = HeaderMap::new();
|
|
headers.insert(header::CONTENT_TYPE, "text/plain".parse().unwrap());
|
|
(headers, "foo")
|
|
}
|
|
|
|
// Or an array of tuples to more easily build the headers
|
|
async fn with_array_headers() -> impl IntoResponse {
|
|
([(header::CONTENT_TYPE, "text/plain")], "foo")
|
|
}
|
|
|
|
// Use string keys for custom headers
|
|
async fn with_array_headers_custom() -> impl IntoResponse {
|
|
([("x-custom", "custom")], "foo")
|
|
}
|
|
|
|
// `(StatusCode, headers, impl IntoResponse)` to set status and add headers
|
|
// `headers` can be either a `HeaderMap` or an array of tuples
|
|
async fn with_status_and_array_headers() -> impl IntoResponse {
|
|
(
|
|
StatusCode::NOT_FOUND,
|
|
[(header::CONTENT_TYPE, "text/plain")],
|
|
"foo",
|
|
)
|
|
}
|
|
|
|
// `(Extension<_>, impl IntoResponse)` to set response extensions
|
|
async fn with_status_extensions() -> impl IntoResponse {
|
|
(
|
|
Extension(Foo("foo")),
|
|
"foo",
|
|
)
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct Foo(&'static str);
|
|
|
|
// Or mix and match all the things
|
|
async fn all_the_things(uri: Uri) -> impl IntoResponse {
|
|
let mut header_map = HeaderMap::new();
|
|
if uri.path() == "/" {
|
|
header_map.insert(header::SERVER, "axum".parse().unwrap());
|
|
}
|
|
|
|
(
|
|
// set status code
|
|
StatusCode::NOT_FOUND,
|
|
// headers with an array
|
|
[("x-custom", "custom")],
|
|
// some extensions
|
|
Extension(Foo("foo")),
|
|
Extension(Foo("bar")),
|
|
// more headers, built dynamically
|
|
header_map,
|
|
// and finally the body
|
|
"foo",
|
|
)
|
|
}
|
|
```
|
|
|
|
In general you can return tuples like:
|
|
|
|
- `(StatusCode, impl IntoResponse)`
|
|
- `(Parts, impl IntoResponse)`
|
|
- `(Response<()>, impl IntoResponse)`
|
|
- `(T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].
|
|
- `(StatusCode, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].
|
|
- `(Parts, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].
|
|
- `(Response<()>, T1, .., Tn, impl IntoResponse)` where `T1` to `Tn` all implement [`IntoResponseParts`].
|
|
|
|
This means you cannot accidentally override the status or body as [`IntoResponseParts`] only allows
|
|
setting headers and extensions.
|
|
|
|
Use [`Response`] for more low level control:
|
|
|
|
```rust,no_run
|
|
use axum::{
|
|
Json,
|
|
response::{IntoResponse, Response},
|
|
body::Body,
|
|
http::StatusCode,
|
|
};
|
|
|
|
async fn response() -> Response {
|
|
Response::builder()
|
|
.status(StatusCode::NOT_FOUND)
|
|
.header("x-foo", "custom header")
|
|
.body(Body::from("not found"))
|
|
.unwrap()
|
|
}
|
|
```
|
|
|
|
# Returning different response types
|
|
|
|
If you need to return multiple response types, and `Result<T, E>` isn't appropriate, you can call
|
|
`.into_response()` to turn things into `axum::response::Response`:
|
|
|
|
```rust
|
|
use axum::{
|
|
response::{IntoResponse, Redirect, Response},
|
|
http::StatusCode,
|
|
};
|
|
|
|
async fn handle() -> Response {
|
|
if something() {
|
|
"All good!".into_response()
|
|
} else if something_else() {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
"Something went wrong...",
|
|
).into_response()
|
|
} else {
|
|
Redirect::to("/").into_response()
|
|
}
|
|
}
|
|
|
|
fn something() -> bool {
|
|
// ...
|
|
# true
|
|
}
|
|
|
|
fn something_else() -> bool {
|
|
// ...
|
|
# true
|
|
}
|
|
```
|
|
|
|
# Regarding `impl IntoResponse`
|
|
|
|
You can use `impl IntoResponse` as the return type from handlers to avoid
|
|
typing large types. For example
|
|
|
|
```rust
|
|
use axum::http::StatusCode;
|
|
|
|
async fn handler() -> (StatusCode, [(&'static str, &'static str); 1], &'static str) {
|
|
(StatusCode::OK, [("x-foo", "bar")], "Hello, World!")
|
|
}
|
|
```
|
|
|
|
Becomes easier using `impl IntoResponse`:
|
|
|
|
```rust
|
|
use axum::{http::StatusCode, response::IntoResponse};
|
|
|
|
async fn impl_into_response() -> impl IntoResponse {
|
|
(StatusCode::OK, [("x-foo", "bar")], "Hello, World!")
|
|
}
|
|
```
|
|
|
|
However `impl IntoResponse` has a few limitations. Firstly it can only be used
|
|
to return a single type:
|
|
|
|
```rust,compile_fail
|
|
use axum::{http::StatusCode, response::IntoResponse};
|
|
|
|
async fn handler() -> impl IntoResponse {
|
|
if check_something() {
|
|
StatusCode::NOT_FOUND
|
|
} else {
|
|
"Hello, World!"
|
|
}
|
|
}
|
|
|
|
fn check_something() -> bool {
|
|
# false
|
|
// ...
|
|
}
|
|
```
|
|
|
|
This function returns either a `StatusCode` or a `&'static str` which `impl
|
|
Trait` doesn't allow.
|
|
|
|
Secondly `impl IntoResponse` can lead to type inference issues when used with
|
|
`Result` and `?`:
|
|
|
|
```rust,compile_fail
|
|
use axum::{http::StatusCode, response::IntoResponse};
|
|
|
|
async fn handler() -> impl IntoResponse {
|
|
create_thing()?;
|
|
Ok(StatusCode::CREATED)
|
|
}
|
|
|
|
fn create_thing() -> Result<(), StatusCode> {
|
|
# Ok(())
|
|
// ...
|
|
}
|
|
```
|
|
|
|
This is because `?` supports using the [`From`] trait to convert to a different
|
|
error type but it doesn't know which type to convert to, because we only
|
|
specified `impl IntoResponse` as the return type.
|
|
|
|
`Result<impl IntoResponse, impl IntoResponse>` doesn't always work either:
|
|
|
|
```rust,compile_fail
|
|
use axum::{http::StatusCode, response::IntoResponse};
|
|
|
|
async fn handler() -> Result<impl IntoResponse, impl IntoResponse> {
|
|
create_thing()?;
|
|
Ok(StatusCode::CREATED)
|
|
}
|
|
|
|
fn create_thing() -> Result<(), StatusCode> {
|
|
# Ok(())
|
|
// ...
|
|
}
|
|
```
|
|
|
|
The solution is to use a concrete error type, such as `Result<impl IntoResponse, StatusCode>`:
|
|
|
|
```rust
|
|
use axum::{http::StatusCode, response::IntoResponse};
|
|
|
|
async fn handler() -> Result<impl IntoResponse, StatusCode> {
|
|
create_thing()?;
|
|
Ok(StatusCode::CREATED)
|
|
}
|
|
|
|
fn create_thing() -> Result<(), StatusCode> {
|
|
# Ok(())
|
|
// ...
|
|
}
|
|
```
|
|
|
|
Because of this it is generally not recommended to use `impl IntoResponse`
|
|
unless you're familiar with the details of how `impl Trait` works.
|
|
|
|
[`IntoResponse`]: crate::response::IntoResponse
|
|
[`IntoResponseParts`]: crate::response::IntoResponseParts
|
|
[`StatusCode`]: http::StatusCode
|
|
|
|
```rust
|
|
pub mod response { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `sse`
|
|
|
|
Server-Sent Events (SSE) responses.
|
|
|
|
# Example
|
|
|
|
```
|
|
use axum::{
|
|
Router,
|
|
routing::get,
|
|
response::sse::{Event, KeepAlive, Sse},
|
|
};
|
|
use std::{time::Duration, convert::Infallible};
|
|
use tokio_stream::StreamExt as _ ;
|
|
use futures_util::stream::{self, Stream};
|
|
|
|
let app = Router::new().route("/sse", get(sse_handler));
|
|
|
|
async fn sse_handler() -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
|
|
// A `Stream` that repeats an event every second
|
|
let stream = stream::repeat_with(|| Event::default().data("hi!"))
|
|
.map(Ok)
|
|
.throttle(Duration::from_secs(1));
|
|
|
|
Sse::new(stream).keep_alive(KeepAlive::default())
|
|
}
|
|
# let _: Router = app;
|
|
```
|
|
|
|
```rust
|
|
pub mod sse { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `Sse`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
An SSE response
|
|
|
|
```rust
|
|
pub struct Sse<S> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn new(stream: S) -> Self
|
|
where
|
|
S: TryStream<Ok = Event> + Send + ''static,
|
|
<S as >::Error: Into<BoxError> { /* ... */ }
|
|
```
|
|
Create a new [`Sse`] response that will respond with the given stream of
|
|
|
|
- ```rust
|
|
pub fn keep_alive(self: Self, keep_alive: KeepAlive) -> Sse<KeepAliveStream<S>> { /* ... */ }
|
|
```
|
|
Configure the interval between keep-alive messages.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Sse<S> { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **HandlerWithoutStateExt**
|
|
- ```rust
|
|
fn into_service(self: Self) -> HandlerService<H, T, ()> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<HandlerService<H, T, ()>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `Event`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
Server-sent event
|
|
|
|
```rust
|
|
pub struct Event {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn into_data_writer(self: Self) -> EventDataWriter { /* ... */ }
|
|
```
|
|
Use this [`Event`] as a [`EventDataWriter`] to write custom data.
|
|
|
|
- ```rust
|
|
pub fn data<T>(self: Self, data: T) -> Self
|
|
where
|
|
T: AsRef<str> { /* ... */ }
|
|
```
|
|
Set the event's data data field(s) (`data: <content>`)
|
|
|
|
- ```rust
|
|
pub fn json_data<T>(self: Self, data: T) -> Result<Self, axum_core::Error>
|
|
where
|
|
T: serde_core::Serialize { /* ... */ }
|
|
```
|
|
Set the event's data field to a value serialized as unformatted JSON (`data: <content>`).
|
|
|
|
- ```rust
|
|
pub fn comment<T>(self: Self, comment: T) -> Event
|
|
where
|
|
T: AsRef<str> { /* ... */ }
|
|
```
|
|
Set the event's comment field (`:<comment-text>`).
|
|
|
|
- ```rust
|
|
pub fn event<T>(self: Self, event: T) -> Event
|
|
where
|
|
T: AsRef<str> { /* ... */ }
|
|
```
|
|
Set the event's name field (`event:<event-name>`).
|
|
|
|
- ```rust
|
|
pub fn retry(self: Self, duration: Duration) -> Event { /* ... */ }
|
|
```
|
|
Set the event's retry timeout field (`retry: <timeout>`).
|
|
|
|
- ```rust
|
|
pub fn id<T>(self: Self, id: T) -> Event
|
|
where
|
|
T: AsRef<str> { /* ... */ }
|
|
```
|
|
Set the event's identifier field (`id:<identifier>`).
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Event { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `EventDataWriter`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
Expose [`Event`] as a [`std::fmt::Write`]
|
|
such that any form of data can be written as data safely.
|
|
|
|
This also ensures that newline characters `\r` and `\n`
|
|
correctly trigger a split with a new `data: ` prefix.
|
|
|
|
# Panics
|
|
|
|
Panics if any `data` has already been written prior to the first write
|
|
of this [`EventDataWriter`] instance.
|
|
|
|
```rust
|
|
pub struct EventDataWriter {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn into_event(self: Self) -> Event { /* ... */ }
|
|
```
|
|
Consume the [`EventDataWriter`] and return the [`Event`] once again.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
- **Write**
|
|
- ```rust
|
|
fn write_str(self: &mut Self, s: &str) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
#### Struct `KeepAlive`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
Configure the interval between keep-alive messages, the content
|
|
of each message, and the associated stream.
|
|
|
|
```rust
|
|
pub struct KeepAlive {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn new() -> Self { /* ... */ }
|
|
```
|
|
Create a new `KeepAlive`.
|
|
|
|
- ```rust
|
|
pub fn interval(self: Self, time: Duration) -> Self { /* ... */ }
|
|
```
|
|
Customize the interval between keep-alive messages.
|
|
|
|
- ```rust
|
|
pub fn text<I>(self: Self, text: I) -> Self
|
|
where
|
|
I: AsRef<str> { /* ... */ }
|
|
```
|
|
Customize the text of the keep-alive message.
|
|
|
|
- ```rust
|
|
pub fn event(self: Self, event: Event) -> Self { /* ... */ }
|
|
```
|
|
Customize the event of the keep-alive message.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> KeepAlive { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `KeepAliveStream`
|
|
|
|
A wrapper around a stream that produces keep-alive events
|
|
|
|
```rust
|
|
pub struct KeepAliveStream<S> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Stream**
|
|
- ```rust
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<''_>) -> Poll<Option<<Self as >::Item>> { /* ... */ }
|
|
```
|
|
|
|
- **StreamExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryStream**
|
|
- ```rust
|
|
fn try_poll_next(self: Pin<&mut S>, cx: &mut Context<''_>) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>> { /* ... */ }
|
|
```
|
|
|
|
- **TryStreamExt**
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Types
|
|
|
|
#### Struct `Html`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
An HTML response.
|
|
|
|
Will automatically get `Content-Type: text/html`.
|
|
|
|
```rust
|
|
pub struct Html<T>(pub T);
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Index | Type | Documentation |
|
|
|-------|------|---------------|
|
|
| 0 | `T` | |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Html<T> { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Copy**
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- ```rust
|
|
fn from(t: never) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn from(inner: T) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **HandlerWithoutStateExt**
|
|
- ```rust
|
|
fn into_service(self: Self) -> HandlerService<H, T, ()> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<HandlerService<H, T, ()>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `NoContent`
|
|
|
|
An empty response with 204 No Content status.
|
|
|
|
Due to historical and implementation reasons, the `IntoResponse` implementation of `()`
|
|
(unit type) returns an empty response with 200 [`StatusCode::OK`] status.
|
|
If you specifically want a 204 [`StatusCode::NO_CONTENT`] status, you can use either `StatusCode` type
|
|
directly, or this shortcut struct for self-documentation.
|
|
|
|
```
|
|
use axum::{extract::Path, response::NoContent};
|
|
|
|
async fn delete_user(Path(user): Path<String>) -> Result<NoContent, String> {
|
|
// ...access database...
|
|
# drop(user);
|
|
Ok(NoContent)
|
|
}
|
|
```
|
|
|
|
```rust
|
|
pub struct NoContent;
|
|
```
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> NoContent { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Copy**
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **HandlerWithoutStateExt**
|
|
- ```rust
|
|
fn into_service(self: Self) -> HandlerService<H, T, ()> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<HandlerService<H, T, ()>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoResponse**
|
|
- ```rust
|
|
fn into_response(self: Self) -> Response { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Re-exports
|
|
|
|
#### Re-export `Json`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
- `Other("#[<cfg_trace>(feature = \"json\")]")`
|
|
|
|
```rust
|
|
pub use crate::Json;
|
|
```
|
|
|
|
#### Re-export `Form`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"form\")]")`
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use crate::form::Form;
|
|
```
|
|
|
|
#### Re-export `Extension`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use crate::Extension;
|
|
```
|
|
|
|
#### Re-export `AppendHeaders`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::AppendHeaders;
|
|
```
|
|
|
|
#### Re-export `ErrorResponse`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::ErrorResponse;
|
|
```
|
|
|
|
#### Re-export `IntoResponse`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::IntoResponse;
|
|
```
|
|
|
|
#### Re-export `IntoResponseParts`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::IntoResponseParts;
|
|
```
|
|
|
|
#### Re-export `Response`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::Response;
|
|
```
|
|
|
|
#### Re-export `ResponseParts`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::ResponseParts;
|
|
```
|
|
|
|
#### Re-export `Result`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::response::Result;
|
|
```
|
|
|
|
#### Re-export `Redirect`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::redirect::Redirect;
|
|
```
|
|
|
|
#### Re-export `Sse`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use sse::Sse;
|
|
```
|
|
|
|
## Module `routing`
|
|
|
|
Routing between [`Service`]s and handlers.
|
|
|
|
```rust
|
|
pub mod routing { /* ... */ }
|
|
```
|
|
|
|
### Modules
|
|
|
|
## Module `future`
|
|
|
|
Future types.
|
|
|
|
```rust
|
|
pub mod future { /* ... */ }
|
|
```
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `IntoMakeServiceFuture`
|
|
|
|
```rust
|
|
pub use super::into_make_service::IntoMakeServiceFuture;
|
|
```
|
|
|
|
#### Re-export `InfallibleRouteFuture`
|
|
|
|
```rust
|
|
pub use super::route::InfallibleRouteFuture;
|
|
```
|
|
|
|
#### Re-export `RouteFuture`
|
|
|
|
```rust
|
|
pub use super::route::RouteFuture;
|
|
```
|
|
|
|
## Module `method_routing`
|
|
|
|
Route to services and handlers based on HTTP methods.
|
|
|
|
```rust
|
|
pub mod method_routing { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `MethodRouter`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
A [`Service`] that accepts requests based on a [`MethodFilter`] and
|
|
allows chaining additional handlers and services.
|
|
|
|
# When does `MethodRouter` implement [`Service`]?
|
|
|
|
Whether or not `MethodRouter` implements [`Service`] depends on the state type it requires.
|
|
|
|
```
|
|
use tower::Service;
|
|
use axum::{routing::get, extract::{State, Request}, body::Body};
|
|
|
|
// this `MethodRouter` doesn't require any state, i.e. the state is `()`,
|
|
let method_router = get(|| async {});
|
|
// and thus it implements `Service`
|
|
assert_service(method_router);
|
|
|
|
// this requires a `String` and doesn't implement `Service`
|
|
let method_router = get(|_: State<String>| async {});
|
|
// until you provide the `String` with `.with_state(...)`
|
|
let method_router_with_state = method_router.with_state(String::new());
|
|
// and then it implements `Service`
|
|
assert_service(method_router_with_state);
|
|
|
|
// helper to check that a value implements `Service`
|
|
fn assert_service<S>(service: S)
|
|
where
|
|
S: Service<Request>,
|
|
{}
|
|
```
|
|
|
|
```rust
|
|
pub struct MethodRouter<S = (), E = std::convert::Infallible> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn on<H, T>(self: Self, filter: MethodFilter, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will accept requests matching the given
|
|
|
|
- ```rust
|
|
pub fn connect<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `CONNECT` requests.
|
|
|
|
- ```rust
|
|
pub fn delete<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `DELETE` requests.
|
|
|
|
- ```rust
|
|
pub fn get<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `GET` requests.
|
|
|
|
- ```rust
|
|
pub fn head<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `HEAD` requests.
|
|
|
|
- ```rust
|
|
pub fn options<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `OPTIONS` requests.
|
|
|
|
- ```rust
|
|
pub fn patch<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `PATCH` requests.
|
|
|
|
- ```rust
|
|
pub fn post<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `POST` requests.
|
|
|
|
- ```rust
|
|
pub fn put<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `PUT` requests.
|
|
|
|
- ```rust
|
|
pub fn trace<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Chain an additional handler that will only accept `TRACE` requests.
|
|
|
|
- ```rust
|
|
pub fn fallback<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Send + Sync + ''static { /* ... */ }
|
|
```
|
|
Add a fallback [`Handler`] to the router.
|
|
|
|
- ```rust
|
|
pub fn into_make_service(self: Self) -> IntoMakeService<Self> { /* ... */ }
|
|
```
|
|
Convert the router into a [`MakeService`].
|
|
|
|
- ```rust
|
|
pub fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<Self, C> { /* ... */ }
|
|
```
|
|
Convert the router into a [`MakeService`] which stores information
|
|
|
|
- ```rust
|
|
pub fn new() -> Self { /* ... */ }
|
|
```
|
|
Create a default `MethodRouter` that will respond with `405 Method Not Allowed` to all
|
|
|
|
- ```rust
|
|
pub fn with_state<S2>(self: Self, state: S) -> MethodRouter<S2, E> { /* ... */ }
|
|
```
|
|
Provide the state for the router.
|
|
|
|
- ```rust
|
|
pub fn on_service<T>(self: Self, filter: MethodFilter, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will accept requests matching the given
|
|
|
|
- ```rust
|
|
pub fn connect_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `CONNECT` requests.
|
|
|
|
- ```rust
|
|
pub fn delete_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `DELETE` requests.
|
|
|
|
- ```rust
|
|
pub fn get_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `GET` requests.
|
|
|
|
- ```rust
|
|
pub fn head_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `HEAD` requests.
|
|
|
|
- ```rust
|
|
pub fn options_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `OPTIONS` requests.
|
|
|
|
- ```rust
|
|
pub fn patch_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `PATCH` requests.
|
|
|
|
- ```rust
|
|
pub fn post_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `POST` requests.
|
|
|
|
- ```rust
|
|
pub fn put_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `PUT` requests.
|
|
|
|
- ```rust
|
|
pub fn trace_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Chain an additional service that will only accept `TRACE` requests.
|
|
|
|
- ```rust
|
|
pub fn fallback_service<T>(self: Self, svc: T) -> Self
|
|
where
|
|
T: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Add a fallback service to the router.
|
|
|
|
- ```rust
|
|
pub fn layer<L, NewError>(self: Self, layer: L) -> MethodRouter<S, NewError>
|
|
where
|
|
L: Layer<Route<E>> + Clone + Send + Sync + ''static,
|
|
<L as >::Service: Service<Request> + Clone + Send + Sync + ''static,
|
|
<<L as >::Service as Service<Request>>::Response: IntoResponse + ''static,
|
|
<<L as >::Service as Service<Request>>::Error: Into<NewError> + ''static,
|
|
<<L as >::Service as Service<Request>>::Future: Send + ''static,
|
|
E: ''static,
|
|
S: ''static,
|
|
NewError: ''static { /* ... */ }
|
|
```
|
|
Apply a [`tower::Layer`] to all routes in the router.
|
|
|
|
- ```rust
|
|
pub fn route_layer<L>(self: Self, layer: L) -> MethodRouter<S, E>
|
|
where
|
|
L: Layer<Route<E>> + Clone + Send + Sync + ''static,
|
|
<L as >::Service: Service<Request, Error = E> + Clone + Send + Sync + ''static,
|
|
<<L as >::Service as Service<Request>>::Response: IntoResponse + ''static,
|
|
<<L as >::Service as Service<Request>>::Future: Send + ''static,
|
|
E: ''static,
|
|
S: ''static { /* ... */ }
|
|
```
|
|
Apply a [`tower::Layer`] to the router that will only run if the request matches
|
|
|
|
- ```rust
|
|
pub fn merge(self: Self, other: MethodRouter<S, E>) -> Self { /* ... */ }
|
|
```
|
|
Merge two routers into one.
|
|
|
|
- ```rust
|
|
pub fn handle_error<F, T>(self: Self, f: F) -> MethodRouter<S, Infallible>
|
|
where
|
|
F: Clone + Send + Sync + ''static,
|
|
HandleError<Route<E>, F, T>: Service<Request, Error = Infallible>,
|
|
<HandleError<Route<E>, F, T> as Service<Request>>::Future: Send,
|
|
<HandleError<Route<E>, F, T> as Service<Request>>::Response: IntoResponse + Send,
|
|
T: ''static,
|
|
E: ''static,
|
|
S: ''static { /* ... */ }
|
|
```
|
|
Apply a [`HandleErrorLayer`].
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Handler**
|
|
- ```rust
|
|
fn call(self: Self, req: Request, state: S) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **HandlerWithoutStateExt**
|
|
- ```rust
|
|
fn into_service(self: Self) -> HandlerService<H, T, ()> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<HandlerService<H, T, ()>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<HandlerService<H, T, ()>, C> { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **MakeService**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll<Result<(), <M as MakeService<Target, Request>>::MakeError>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn make_service(self: &mut Self, target: Target) -> <M as MakeService<Target, Request>>::Future { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<S> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<S, C> { /* ... */ }
|
|
```
|
|
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Functions
|
|
|
|
#### Function `connect_service`
|
|
|
|
Route `CONNECT` requests to the given service.
|
|
|
|
See [`MethodFilter::CONNECT`] for when you'd want to use this,
|
|
and [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn connect_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `delete_service`
|
|
|
|
Route `DELETE` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn delete_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `get_service`
|
|
|
|
Route `GET` requests to the given service.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::{
|
|
extract::Request,
|
|
Router,
|
|
routing::get_service,
|
|
body::Body,
|
|
};
|
|
use http::Response;
|
|
use std::convert::Infallible;
|
|
|
|
let service = tower::service_fn(|request: Request| async {
|
|
Ok::<_, Infallible>(Response::new(Body::empty()))
|
|
});
|
|
|
|
// Requests to `GET /` will go to `service`.
|
|
let app = Router::new().route("/", get_service(service));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
Note that `get` routes will also be called for `HEAD` requests but will have
|
|
the response body removed. Make sure to add explicit `HEAD` routes
|
|
afterwards.
|
|
|
|
```rust
|
|
pub fn get_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `head_service`
|
|
|
|
Route `HEAD` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn head_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `options_service`
|
|
|
|
Route `OPTIONS` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn options_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `patch_service`
|
|
|
|
Route `PATCH` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn patch_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `post_service`
|
|
|
|
Route `POST` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn post_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `put_service`
|
|
|
|
Route `PUT` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn put_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `trace_service`
|
|
|
|
Route `TRACE` requests to the given service.
|
|
|
|
See [`get_service`] for an example.
|
|
|
|
```rust
|
|
pub fn trace_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `on_service`
|
|
|
|
Route requests with the given method to the service.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::{
|
|
extract::Request,
|
|
routing::on,
|
|
Router,
|
|
body::Body,
|
|
routing::{MethodFilter, on_service},
|
|
};
|
|
use http::Response;
|
|
use std::convert::Infallible;
|
|
|
|
let service = tower::service_fn(|request: Request| async {
|
|
Ok::<_, Infallible>(Response::new(Body::empty()))
|
|
});
|
|
|
|
// Requests to `POST /` will go to `service`.
|
|
let app = Router::new().route("/", on_service(MethodFilter::POST, service));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
```rust
|
|
pub fn on_service<T, S>(filter: crate::routing::MethodFilter, svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<axum_core::extract::Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `any_service`
|
|
|
|
Route requests to the given service regardless of its method.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::{
|
|
extract::Request,
|
|
Router,
|
|
routing::any_service,
|
|
body::Body,
|
|
};
|
|
use http::Response;
|
|
use std::convert::Infallible;
|
|
|
|
let service = tower::service_fn(|request: Request| async {
|
|
Ok::<_, Infallible>(Response::new(Body::empty()))
|
|
});
|
|
|
|
// All requests to `/` will go to `service`.
|
|
let app = Router::new().route("/", any_service(service));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
Additional methods can still be chained:
|
|
|
|
```rust
|
|
use axum::{
|
|
extract::Request,
|
|
Router,
|
|
routing::any_service,
|
|
body::Body,
|
|
};
|
|
use http::Response;
|
|
use std::convert::Infallible;
|
|
|
|
let service = tower::service_fn(|request: Request| async {
|
|
# Ok::<_, Infallible>(Response::new(Body::empty()))
|
|
// ...
|
|
});
|
|
|
|
let other_service = tower::service_fn(|request: Request| async {
|
|
# Ok::<_, Infallible>(Response::new(Body::empty()))
|
|
// ...
|
|
});
|
|
|
|
// `POST /` goes to `other_service`. All other requests go to `service`
|
|
let app = Router::new().route("/", any_service(service).post_service(other_service));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
```rust
|
|
pub fn any_service<T, S>(svc: T) -> MethodRouter<S, <T as >::Error>
|
|
where
|
|
T: Service<axum_core::extract::Request> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse + ''static,
|
|
<T as >::Future: Send + ''static,
|
|
S: Clone { /* ... */ }
|
|
```
|
|
|
|
#### Function `connect`
|
|
|
|
Route `CONNECT` requests to the given handler.
|
|
|
|
See [`MethodFilter::CONNECT`] for when you'd want to use this,
|
|
and [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn connect<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `delete`
|
|
|
|
Route `DELETE` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn delete<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `get`
|
|
|
|
Route `GET` requests to the given handler.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::get,
|
|
Router,
|
|
};
|
|
|
|
async fn handler() {}
|
|
|
|
// Requests to `GET /` will go to `handler`.
|
|
let app = Router::new().route("/", get(handler));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
Note that `get` routes will also be called for `HEAD` requests but will have
|
|
the response body removed. Make sure to add explicit `HEAD` routes
|
|
afterwards.
|
|
|
|
```rust
|
|
pub fn get<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `head`
|
|
|
|
Route `HEAD` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn head<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `options`
|
|
|
|
Route `OPTIONS` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn options<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `patch`
|
|
|
|
Route `PATCH` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn patch<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `post`
|
|
|
|
Route `POST` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn post<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `put`
|
|
|
|
Route `PUT` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn put<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `trace`
|
|
|
|
Route `TRACE` requests to the given handler.
|
|
|
|
See [`get`] for an example.
|
|
|
|
```rust
|
|
pub fn trace<H, T, S>(handler: H) -> MethodRouter<S, Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `on`
|
|
|
|
Route requests with the given method to the handler.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::on,
|
|
Router,
|
|
routing::MethodFilter,
|
|
};
|
|
|
|
async fn handler() {}
|
|
|
|
// Requests to `POST /` will go to `handler`.
|
|
let app = Router::new().route("/", on(MethodFilter::POST, handler));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
```rust
|
|
pub fn on<H, T, S>(filter: crate::routing::MethodFilter, handler: H) -> MethodRouter<S, std::convert::Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
#### Function `any`
|
|
|
|
Route requests with the given handler regardless of the method.
|
|
|
|
# Example
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::any,
|
|
Router,
|
|
};
|
|
|
|
async fn handler() {}
|
|
|
|
// All requests to `/` will go to `handler`.
|
|
let app = Router::new().route("/", any(handler));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
Additional methods can still be chained:
|
|
|
|
```rust
|
|
use axum::{
|
|
routing::any,
|
|
Router,
|
|
};
|
|
|
|
async fn handler() {}
|
|
|
|
async fn other_handler() {}
|
|
|
|
// `POST /` goes to `other_handler`. All other requests go to `handler`
|
|
let app = Router::new().route("/", any(handler).post(other_handler));
|
|
# let _: Router = app;
|
|
```
|
|
|
|
```rust
|
|
pub fn any<H, T, S>(handler: H) -> MethodRouter<S, std::convert::Infallible>
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static,
|
|
S: Clone + Send + Sync + ''static { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `Router`
|
|
|
|
**Attributes:**
|
|
|
|
- `MustUse { reason: None }`
|
|
|
|
The router type for composing handlers and services.
|
|
|
|
`Router<S>` means a router that is _missing_ a state of type `S` to be able
|
|
to handle requests. Thus, only `Router<()>` (i.e. without missing state) can
|
|
be passed to [`serve`]. See [`Router::with_state`] for more details.
|
|
|
|
[`serve`]: crate::serve()
|
|
|
|
```rust
|
|
pub struct Router<S = ()> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn new() -> Self { /* ... */ }
|
|
```
|
|
Create a new `Router`.
|
|
|
|
- ```rust
|
|
pub fn without_v07_checks(self: Self) -> Self { /* ... */ }
|
|
```
|
|
Turn off checks for compatibility with route matching syntax from 0.7.
|
|
|
|
- ```rust
|
|
pub fn route(self: Self, path: &str, method_router: MethodRouter<S>) -> Self { /* ... */ }
|
|
```
|
|
Add another route to the router.
|
|
|
|
- ```rust
|
|
pub fn route_service<T>(self: Self, path: &str, service: T) -> Self
|
|
where
|
|
T: Service<Request, Error = Infallible> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Add another route to the router that calls a [`Service`].
|
|
|
|
- ```rust
|
|
pub fn nest(self: Self, path: &str, router: Router<S>) -> Self { /* ... */ }
|
|
```
|
|
Nest a [`Router`] at some path.
|
|
|
|
- ```rust
|
|
pub fn nest_service<T>(self: Self, path: &str, service: T) -> Self
|
|
where
|
|
T: Service<Request, Error = Infallible> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Like [`nest`](Self::nest), but accepts an arbitrary `Service`.
|
|
|
|
- ```rust
|
|
pub fn merge<R>(self: Self, other: R) -> Self
|
|
where
|
|
R: Into<Router<S>> { /* ... */ }
|
|
```
|
|
Merge the paths and fallbacks of two routers into a single [`Router`].
|
|
|
|
- ```rust
|
|
pub fn layer<L>(self: Self, layer: L) -> Router<S>
|
|
where
|
|
L: Layer<Route> + Clone + Send + Sync + ''static,
|
|
<L as >::Service: Service<Request> + Clone + Send + Sync + ''static,
|
|
<<L as >::Service as Service<Request>>::Response: IntoResponse + ''static,
|
|
<<L as >::Service as Service<Request>>::Error: Into<Infallible> + ''static,
|
|
<<L as >::Service as Service<Request>>::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Apply a [`tower::Layer`] to all routes in the router.
|
|
|
|
- ```rust
|
|
pub fn route_layer<L>(self: Self, layer: L) -> Self
|
|
where
|
|
L: Layer<Route> + Clone + Send + Sync + ''static,
|
|
<L as >::Service: Service<Request> + Clone + Send + Sync + ''static,
|
|
<<L as >::Service as Service<Request>>::Response: IntoResponse + ''static,
|
|
<<L as >::Service as Service<Request>>::Error: Into<Infallible> + ''static,
|
|
<<L as >::Service as Service<Request>>::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Apply a [`tower::Layer`] to the router that will only run if the request matches
|
|
|
|
- ```rust
|
|
pub fn has_routes(self: &Self) -> bool { /* ... */ }
|
|
```
|
|
True if the router currently has at least one route added.
|
|
|
|
- ```rust
|
|
pub fn fallback<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static { /* ... */ }
|
|
```
|
|
Add a fallback [`Handler`] to the router.
|
|
|
|
- ```rust
|
|
pub fn fallback_service<T>(self: Self, service: T) -> Self
|
|
where
|
|
T: Service<Request, Error = Infallible> + Clone + Send + Sync + ''static,
|
|
<T as >::Response: IntoResponse,
|
|
<T as >::Future: Send + ''static { /* ... */ }
|
|
```
|
|
Add a fallback [`Service`] to the router.
|
|
|
|
- ```rust
|
|
pub fn method_not_allowed_fallback<H, T>(self: Self, handler: H) -> Self
|
|
where
|
|
H: Handler<T, S>,
|
|
T: ''static { /* ... */ }
|
|
```
|
|
Add a fallback [`Handler`] for the case where a route exists, but the method of the request is not supported.
|
|
|
|
- ```rust
|
|
pub fn reset_fallback(self: Self) -> Self { /* ... */ }
|
|
```
|
|
Reset the fallback to its default.
|
|
|
|
- ```rust
|
|
pub fn with_state<S2>(self: Self, state: S) -> Router<S2> { /* ... */ }
|
|
```
|
|
Provide the state for the router. State passed to this method is global and will be used
|
|
|
|
- ```rust
|
|
pub fn as_service<B>(self: &mut Self) -> RouterAsService<''_, B, S> { /* ... */ }
|
|
```
|
|
Convert the router into a borrowed [`Service`] with a fixed request body type, to aid type
|
|
|
|
- ```rust
|
|
pub fn into_service<B>(self: Self) -> RouterIntoService<B, S> { /* ... */ }
|
|
```
|
|
Convert the router into an owned [`Service`] with a fixed request body type, to aid type
|
|
|
|
- ```rust
|
|
pub fn into_make_service(self: Self) -> IntoMakeService<Self> { /* ... */ }
|
|
```
|
|
Convert this router into a [`MakeService`], that is a [`Service`] whose
|
|
|
|
- ```rust
|
|
pub fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<Self, C> { /* ... */ }
|
|
```
|
|
Convert this router into a [`MakeService`], that will store `C`'s
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **Default**
|
|
- ```rust
|
|
fn default() -> Self { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **MakeService**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll<Result<(), <M as MakeService<Target, Request>>::MakeError>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn make_service(self: &mut Self, target: Target) -> <M as MakeService<Target, Request>>::Future { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<S> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<S, C> { /* ... */ }
|
|
```
|
|
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `RouterAsService`
|
|
|
|
A [`Router`] converted into a borrowed [`Service`] with a fixed body type.
|
|
|
|
See [`Router::as_service`] for more details.
|
|
|
|
```rust
|
|
pub struct RouterAsService<''a, B, S = ()> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<S> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<S, C> { /* ... */ }
|
|
```
|
|
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `RouterIntoService`
|
|
|
|
A [`Router`] converted into an owned [`Service`] with a fixed body type.
|
|
|
|
See [`Router::into_service`] for more details.
|
|
|
|
```rust
|
|
pub struct RouterIntoService<B, S = ()> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Clone**
|
|
- ```rust
|
|
fn clone(self: &Self) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **CloneToUninit**
|
|
- ```rust
|
|
unsafe fn clone_to_uninit(self: &Self, dest: *mut u8) { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut fmt::Formatter<''_>) -> fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **FromRef**
|
|
- ```rust
|
|
fn from_ref(input: &T) -> T { /* ... */ }
|
|
```
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, req: Request<B>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- ```rust
|
|
fn into_make_service(self: Self) -> IntoMakeService<S> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn into_make_service_with_connect_info<C>(self: Self) -> IntoMakeServiceWithConnectInfo<S, C> { /* ... */ }
|
|
```
|
|
|
|
- **Sync**
|
|
- **ToOwned**
|
|
- ```rust
|
|
fn to_owned(self: &Self) -> T { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn clone_into(self: &Self, target: &mut T) { /* ... */ }
|
|
```
|
|
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Re-exports
|
|
|
|
#### Re-export `IntoMakeService`
|
|
|
|
```rust
|
|
pub use self::into_make_service::IntoMakeService;
|
|
```
|
|
|
|
#### Re-export `MethodFilter`
|
|
|
|
```rust
|
|
pub use self::method_filter::MethodFilter;
|
|
```
|
|
|
|
#### Re-export `Route`
|
|
|
|
```rust
|
|
pub use self::route::Route;
|
|
```
|
|
|
|
#### Re-export `any`
|
|
|
|
```rust
|
|
pub use self::method_routing::any;
|
|
```
|
|
|
|
#### Re-export `any_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::any_service;
|
|
```
|
|
|
|
#### Re-export `connect`
|
|
|
|
```rust
|
|
pub use self::method_routing::connect;
|
|
```
|
|
|
|
#### Re-export `connect_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::connect_service;
|
|
```
|
|
|
|
#### Re-export `delete`
|
|
|
|
```rust
|
|
pub use self::method_routing::delete;
|
|
```
|
|
|
|
#### Re-export `delete_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::delete_service;
|
|
```
|
|
|
|
#### Re-export `get`
|
|
|
|
```rust
|
|
pub use self::method_routing::get;
|
|
```
|
|
|
|
#### Re-export `get_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::get_service;
|
|
```
|
|
|
|
#### Re-export `head`
|
|
|
|
```rust
|
|
pub use self::method_routing::head;
|
|
```
|
|
|
|
#### Re-export `head_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::head_service;
|
|
```
|
|
|
|
#### Re-export `on`
|
|
|
|
```rust
|
|
pub use self::method_routing::on;
|
|
```
|
|
|
|
#### Re-export `on_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::on_service;
|
|
```
|
|
|
|
#### Re-export `options`
|
|
|
|
```rust
|
|
pub use self::method_routing::options;
|
|
```
|
|
|
|
#### Re-export `options_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::options_service;
|
|
```
|
|
|
|
#### Re-export `patch`
|
|
|
|
```rust
|
|
pub use self::method_routing::patch;
|
|
```
|
|
|
|
#### Re-export `patch_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::patch_service;
|
|
```
|
|
|
|
#### Re-export `post`
|
|
|
|
```rust
|
|
pub use self::method_routing::post;
|
|
```
|
|
|
|
#### Re-export `post_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::post_service;
|
|
```
|
|
|
|
#### Re-export `put`
|
|
|
|
```rust
|
|
pub use self::method_routing::put;
|
|
```
|
|
|
|
#### Re-export `put_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::put_service;
|
|
```
|
|
|
|
#### Re-export `trace`
|
|
|
|
```rust
|
|
pub use self::method_routing::trace;
|
|
```
|
|
|
|
#### Re-export `trace_service`
|
|
|
|
```rust
|
|
pub use self::method_routing::trace_service;
|
|
```
|
|
|
|
#### Re-export `MethodRouter`
|
|
|
|
```rust
|
|
pub use self::method_routing::MethodRouter;
|
|
```
|
|
|
|
## Module `serve`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")`
|
|
|
|
Serve services.
|
|
|
|
```rust
|
|
pub mod serve { /* ... */ }
|
|
```
|
|
|
|
### Types
|
|
|
|
#### Struct `Serve`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")`
|
|
- `MustUse { reason: Some("futures must be awaited or polled") }`
|
|
|
|
Future returned by [`serve`].
|
|
|
|
```rust
|
|
pub struct Serve<L, M, S> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn with_graceful_shutdown<F>(self: Self, signal: F) -> WithGracefulShutdown<L, M, S, F>
|
|
where
|
|
F: Future<Output = ()> + Send + ''static { /* ... */ }
|
|
```
|
|
Prepares a server to handle graceful shutdown when the provided future completes.
|
|
|
|
- ```rust
|
|
pub fn local_addr(self: &Self) -> io::Result<<L as >::Addr> { /* ... */ }
|
|
```
|
|
Returns the local address this server is bound to.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoFuture**
|
|
- ```rust
|
|
fn into_future(self: Self) -> <Self as >::IntoFuture { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `WithGracefulShutdown`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")`
|
|
- `MustUse { reason: Some("futures must be awaited or polled") }`
|
|
|
|
Serve future with graceful shutdown enabled.
|
|
|
|
```rust
|
|
pub struct WithGracefulShutdown<L, M, S, F> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn local_addr(self: &Self) -> io::Result<<L as >::Addr> { /* ... */ }
|
|
```
|
|
Returns the local address this server is bound to.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut std::fmt::Formatter<''_>) -> std::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **IntoFuture**
|
|
- ```rust
|
|
fn into_future(self: Self) -> <Self as >::IntoFuture { /* ... */ }
|
|
```
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
#### Struct `IncomingStream`
|
|
|
|
An incoming stream.
|
|
|
|
Used with [`serve`] and [`IntoMakeServiceWithConnectInfo`].
|
|
|
|
[`IntoMakeServiceWithConnectInfo`]: crate::extract::connect_info::IntoMakeServiceWithConnectInfo
|
|
|
|
```rust
|
|
pub struct IncomingStream<''a, L> {
|
|
// Some fields omitted
|
|
}
|
|
```
|
|
|
|
##### Fields
|
|
|
|
| Name | Type | Documentation |
|
|
|------|------|---------------|
|
|
| *private fields* | ... | *Some fields have been omitted* |
|
|
|
|
##### Implementations
|
|
|
|
###### Methods
|
|
|
|
- ```rust
|
|
pub fn io(self: &Self) -> &<L as >::Io { /* ... */ }
|
|
```
|
|
Get a reference to the inner IO type.
|
|
|
|
- ```rust
|
|
pub fn remote_addr(self: &Self) -> &<L as >::Addr { /* ... */ }
|
|
```
|
|
Returns the remote address that this stream is bound to.
|
|
|
|
###### Trait Implementations
|
|
|
|
- **Any**
|
|
- ```rust
|
|
fn type_id(self: &Self) -> TypeId { /* ... */ }
|
|
```
|
|
|
|
- **Borrow**
|
|
- ```rust
|
|
fn borrow(self: &Self) -> &T { /* ... */ }
|
|
```
|
|
|
|
- **BorrowMut**
|
|
- ```rust
|
|
fn borrow_mut(self: &mut Self) -> &mut T { /* ... */ }
|
|
```
|
|
|
|
- **Connected**
|
|
- ```rust
|
|
fn connect_info(stream: serve::IncomingStream<''_, TcpListener>) -> Self { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn connect_info(stream: serve::IncomingStream<''a, serve::TapIo<L, F>>) -> Self { /* ... */ }
|
|
```
|
|
|
|
- **Debug**
|
|
- ```rust
|
|
fn fmt(self: &Self, f: &mut $crate::fmt::Formatter<''_>) -> $crate::fmt::Result { /* ... */ }
|
|
```
|
|
|
|
- **ErasedDestructor**
|
|
- **Freeze**
|
|
- **From**
|
|
- ```rust
|
|
fn from(t: T) -> T { /* ... */ }
|
|
```
|
|
Returns the argument unchanged.
|
|
|
|
- **Instrument**
|
|
- **Into**
|
|
- ```rust
|
|
fn into(self: Self) -> U { /* ... */ }
|
|
```
|
|
Calls `U::from(self)`.
|
|
|
|
- **PolicyExt**
|
|
- ```rust
|
|
fn and<P, B, E>(self: Self, other: P) -> And<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn or<P, B, E>(self: Self, other: P) -> Or<T, P>
|
|
where
|
|
T: Policy<B, E>,
|
|
P: Policy<B, E> { /* ... */ }
|
|
```
|
|
|
|
- **RefUnwindSafe**
|
|
- **Same**
|
|
- **Send**
|
|
- **Service**
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn poll_ready(self: &mut Self, _cx: &mut Context<''_>) -> Poll<Result<(), <Self as >::Error>> { /* ... */ }
|
|
```
|
|
|
|
- ```rust
|
|
fn call(self: &mut Self, _req: serve::IncomingStream<''_, L>) -> <Self as >::Future { /* ... */ }
|
|
```
|
|
|
|
- **ServiceExt**
|
|
- **Sync**
|
|
- **TryFrom**
|
|
- ```rust
|
|
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **TryInto**
|
|
- ```rust
|
|
fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error> { /* ... */ }
|
|
```
|
|
|
|
- **Unpin**
|
|
- **UnwindSafe**
|
|
- **VZip**
|
|
- ```rust
|
|
fn vzip(self: Self) -> V { /* ... */ }
|
|
```
|
|
|
|
- **WithSubscriber**
|
|
### Functions
|
|
|
|
#### Function `serve`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")`
|
|
|
|
Serve the service with the supplied listener.
|
|
|
|
This method of running a service is intentionally simple and doesn't support any configuration.
|
|
Use hyper or hyper-util if you need configuration.
|
|
|
|
It supports both HTTP/1 as well as HTTP/2.
|
|
|
|
# Examples
|
|
|
|
Serving a [`Router`]:
|
|
|
|
```
|
|
use axum::{Router, routing::get};
|
|
|
|
# async {
|
|
let router = Router::new().route("/", get(|| async { "Hello, World!" }));
|
|
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
|
axum::serve(listener, router).await.unwrap();
|
|
# };
|
|
```
|
|
|
|
See also [`Router::into_make_service_with_connect_info`].
|
|
|
|
Serving a [`MethodRouter`]:
|
|
|
|
```
|
|
use axum::routing::get;
|
|
|
|
# async {
|
|
let router = get(|| async { "Hello, World!" });
|
|
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
|
axum::serve(listener, router).await.unwrap();
|
|
# };
|
|
```
|
|
|
|
See also [`MethodRouter::into_make_service_with_connect_info`].
|
|
|
|
Serving a [`Handler`]:
|
|
|
|
```
|
|
use axum::handler::HandlerWithoutStateExt;
|
|
|
|
# async {
|
|
async fn handler() -> &'static str {
|
|
"Hello, World!"
|
|
}
|
|
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
|
axum::serve(listener, handler.into_make_service()).await.unwrap();
|
|
# };
|
|
```
|
|
|
|
See also [`HandlerWithoutStateExt::into_make_service_with_connect_info`] and
|
|
[`HandlerService::into_make_service_with_connect_info`].
|
|
|
|
# Return Value
|
|
|
|
Although this future resolves to `io::Result<()>`, it will never actually complete or return an
|
|
error. Errors on the TCP socket will be handled by sleeping for a short while (currently, one
|
|
second).
|
|
|
|
[`Router`]: crate::Router
|
|
[`Router::into_make_service_with_connect_info`]: crate::Router::into_make_service_with_connect_info
|
|
[`MethodRouter`]: crate::routing::MethodRouter
|
|
[`MethodRouter::into_make_service_with_connect_info`]: crate::routing::MethodRouter::into_make_service_with_connect_info
|
|
[`Handler`]: crate::handler::Handler
|
|
[`HandlerWithoutStateExt::into_make_service_with_connect_info`]: crate::handler::HandlerWithoutStateExt::into_make_service_with_connect_info
|
|
[`HandlerService::into_make_service_with_connect_info`]: crate::handler::HandlerService::into_make_service_with_connect_info
|
|
|
|
```rust
|
|
pub fn serve<L, M, S>(listener: L, make_service: M) -> Serve<L, M, S>
|
|
where
|
|
L: Listener,
|
|
M: for<''a> Service<IncomingStream<''a, L>, Error = std::convert::Infallible, Response = S>,
|
|
S: Service<axum_core::extract::Request, Response = axum_core::response::Response, Error = std::convert::Infallible> + Clone + Send + ''static,
|
|
<S as >::Future: Send { /* ... */ }
|
|
```
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `Listener`
|
|
|
|
```rust
|
|
pub use self::listener::Listener;
|
|
```
|
|
|
|
#### Re-export `ListenerExt`
|
|
|
|
```rust
|
|
pub use self::listener::ListenerExt;
|
|
```
|
|
|
|
#### Re-export `TapIo`
|
|
|
|
```rust
|
|
pub use self::listener::TapIo;
|
|
```
|
|
|
|
## Module `test_helpers`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(any(test, feature = \"__private\"))]")`
|
|
- `Other("#[allow(missing_docs, missing_debug_implementations, clippy::print_stdout)]")`
|
|
- `Other("#[allow(clippy::disallowed_names)]")`
|
|
|
|
```rust
|
|
pub mod test_helpers { /* ... */ }
|
|
```
|
|
|
|
### Re-exports
|
|
|
|
#### Re-export `self::test_client::*`
|
|
|
|
```rust
|
|
pub use self::test_client::*;
|
|
```
|
|
|
|
## Re-exports
|
|
|
|
### Re-export `http`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(no_inline)]")`
|
|
|
|
```rust
|
|
pub use http;
|
|
```
|
|
|
|
### Re-export `Extension`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::extension::Extension;
|
|
```
|
|
|
|
### Re-export `Json`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
- `Other("#[<cfg_trace>(feature = \"json\")]")`
|
|
|
|
```rust
|
|
pub use self::json::Json;
|
|
```
|
|
|
|
### Re-export `Router`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::routing::Router;
|
|
```
|
|
|
|
### Re-export `Form`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
- `Other("#[<cfg_trace>(feature = \"form\")]")`
|
|
|
|
```rust
|
|
pub use self::form::Form;
|
|
```
|
|
|
|
### Re-export `BoxError`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::BoxError;
|
|
```
|
|
|
|
### Re-export `Error`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::Error;
|
|
```
|
|
|
|
### Re-export `RequestExt`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::RequestExt;
|
|
```
|
|
|
|
### Re-export `RequestPartsExt`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use axum_core::RequestPartsExt;
|
|
```
|
|
|
|
### Re-export `debug_handler`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"macros\")]")`
|
|
|
|
```rust
|
|
pub use axum_macros::debug_handler;
|
|
```
|
|
|
|
### Re-export `debug_middleware`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(feature = \"macros\")]")`
|
|
|
|
```rust
|
|
pub use axum_macros::debug_middleware;
|
|
```
|
|
|
|
### Re-export `serve`
|
|
|
|
**Attributes:**
|
|
|
|
- `Other("#[<cfg_trace>(all(feature = \"tokio\",\nany(feature = \"http1\", feature = \"http2\")))]")`
|
|
- `Other("#[doc(inline)]")`
|
|
|
|
```rust
|
|
pub use self::serve::serve;
|
|
```
|
|
|
|
### Re-export `ServiceExt`
|
|
|
|
```rust
|
|
pub use self::service_ext::ServiceExt;
|
|
```
|
|
|