Make JSON and HTTP1 support optional (#286)

* Make json support an optional feature

* Fix Json type documentation

* Make hyper's http1 feature optional
This commit is contained in:
Jonas Platte 2021-10-02 15:46:33 +02:00 committed by GitHub
parent cc4ae6b297
commit 250ea0cfef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 28 additions and 8 deletions

View file

@ -15,8 +15,10 @@ repository = "https://github.com/tokio-rs/axum"
members = ["examples/*"]
[features]
default = ["tower-log"]
default = ["http1", "json", "tower-log"]
http1 = ["hyper/http1"]
http2 = ["hyper/http2"]
json = ["serde_json"]
multipart = ["multer", "mime"]
tower-log = ["tower/log"]
ws = ["tokio-tungstenite", "sha-1", "base64"]
@ -28,11 +30,11 @@ bytes = "1.0"
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
http = "0.2"
http-body = "0.4.3"
hyper = { version = "0.14", features = ["server", "tcp", "http1", "stream"] }
hyper = { version = "0.14", features = ["server", "tcp", "stream"] }
pin-project-lite = "0.2.7"
regex = "1.5"
serde = "1.0"
serde_json = "1.0"
serde_json = { version = "1.0", optional = true }
serde_urlencoded = "0.7"
tokio = { version = "1", features = ["time"] }
tokio-util = "0.6"
@ -54,6 +56,7 @@ mime = { optional = true, version = "0.3" }
futures = "0.3"
reqwest = { version = "0.11", features = ["json", "stream"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tokio = { version = "1.6.1", features = ["macros", "rt", "rt-multi-thread", "net"] }
uuid = { version = "0.8", features = ["serde", "v4"] }
tokio-stream = "0.1"

View file

@ -192,6 +192,7 @@ pub use self::{
request_parts::{BodyStream, RawBody},
};
#[doc(no_inline)]
#[cfg(feature = "json")]
pub use crate::Json;
#[cfg(feature = "multipart")]

View file

@ -25,9 +25,11 @@ define_rejection! {
pub struct HeadersAlreadyExtracted;
}
#[cfg(feature = "json")]
define_rejection! {
#[status = BAD_REQUEST]
#[body = "Failed to parse the request body as JSON"]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
/// Rejection type for [`Json`](super::Json).
pub struct InvalidJsonBody(Error);
}
@ -199,11 +201,13 @@ composite_rejection! {
}
}
#[cfg(feature = "json")]
composite_rejection! {
/// Rejection used for [`Json`](super::Json).
///
/// Contains one variant for each way the [`Json`](super::Json) extractor
/// can fail.
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub enum JsonRejection {
InvalidJsonBody,
MissingJsonContentType,

View file

@ -17,10 +17,10 @@ use std::{
ops::{Deref, DerefMut},
};
/// JSON Extractor/Response
/// JSON Extractor / Response.
///
/// When used as an extractor, it can deserialize request bodies into some type that
/// implements [`serde::Serialize`]. If the request body cannot be parsed, or it does not contain
/// implements [`serde::Deserialize`]. If the request body cannot be parsed, or it does not contain
/// the `Content-Type: application/json` header, it will reject the request and return a
/// `400 Bad Request` response.
///
@ -87,6 +87,7 @@ use std::{
/// # };
/// ```
#[derive(Debug, Clone, Copy, Default)]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub struct Json<T>(pub T);
#[async_trait]

View file

@ -1120,7 +1120,10 @@
//! The following optional features are available:
//!
//! - `headers`: Enables extracting typed headers via [`extract::TypedHeader`].
//! - `http1`: Enables hyper's `http1` feature. Enabled by default.
//! - `http2`: Enables hyper's `http2` feature.
//! - `json`: Enables the [`Json`] type and some similar convenience functionality.
//! Enabled by default.
//! - `multipart`: Enables parsing `multipart/form-data` requests with [`extract::Multipart`].
//! - `tower-log`: Enables `tower`'s `log` feature. Enabled by default.
//! - `ws`: Enables WebSockets support via [`extract::ws`].
@ -1193,6 +1196,7 @@ pub(crate) mod macros;
mod clone_box_service;
mod error;
#[cfg(feature = "json")]
mod json;
mod util;
@ -1216,7 +1220,10 @@ pub use hyper::Server;
pub use tower_http::add_extension::{AddExtension, AddExtensionLayer};
#[doc(inline)]
pub use self::{error::Error, json::Json, routing::Router};
#[cfg(feature = "json")]
pub use self::json::Json;
#[doc(inline)]
pub use self::{error::Error, routing::Router};
/// Alias for a type-erased error type.
pub type BoxError = Box<dyn std::error::Error + Send + Sync>;

View file

@ -18,6 +18,7 @@ mod redirect;
pub mod sse;
#[doc(no_inline)]
#[cfg(feature = "json")]
pub use crate::Json;
#[doc(inline)]

View file

@ -37,7 +37,6 @@ use futures_util::{
use http::Response;
use http_body::Body as HttpBody;
use pin_project_lite::pin_project;
use serde::Serialize;
use std::{
borrow::Cow,
fmt,
@ -181,6 +180,7 @@ pub struct Event {
#[derive(Debug)]
enum DataType {
Text(String),
#[cfg(feature = "json")]
Json(String),
}
@ -197,9 +197,11 @@ impl Event {
/// Set Server-sent event data
/// data field(s) ("data:<content>")
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
pub fn json_data<T>(mut self, data: T) -> Result<Event, serde_json::Error>
where
T: Serialize,
T: serde::Serialize,
{
self.data = Some(DataType::Json(serde_json::to_string(&data)?));
Ok(self)
@ -265,6 +267,7 @@ impl fmt::Display for Event {
f.write_char('\n')?;
}
}
#[cfg(feature = "json")]
Some(DataType::Json(data)) => {
"data:".fmt(f)?;
data.fmt(f)?;