mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-07 00:00:12 +02:00
Add axum_extra::response::ErasedJson (#537)
This commit is contained in:
@@ -10,5 +10,10 @@ readme = "README.md"
|
|||||||
repository = "https://github.com/tokio-rs/axum"
|
repository = "https://github.com/tokio-rs/axum"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
erased-json = ["serde", "serde_json"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = { path = "../axum", version = "0.3" }
|
axum = { path = "../axum", version = "0.3" }
|
||||||
|
serde = { version = "1.0.130", optional = true }
|
||||||
|
serde_json = { version = "1.0.71", optional = true }
|
||||||
|
|||||||
@@ -41,3 +41,5 @@
|
|||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
#![cfg_attr(test, allow(clippy::float_cmp))]
|
#![cfg_attr(test, allow(clippy::float_cmp))]
|
||||||
|
|
||||||
|
pub mod response;
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
use std::convert::Infallible;
|
||||||
|
|
||||||
|
use axum::{
|
||||||
|
body::{Bytes, Full},
|
||||||
|
http::{header, HeaderValue, Response, StatusCode},
|
||||||
|
response::IntoResponse,
|
||||||
|
};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
/// A response type that holds a JSON in serialized form.
|
||||||
|
///
|
||||||
|
/// This allows returning a borrowing type from a handler, or returning different response
|
||||||
|
/// types as JSON from different branches inside a handler.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use axum::{response::IntoResponse};
|
||||||
|
/// # use axum_extra::response::ErasedJson;
|
||||||
|
/// async fn handler() -> impl IntoResponse {
|
||||||
|
/// # let condition = true;
|
||||||
|
/// # let foo = ();
|
||||||
|
/// # let bar = vec![()];
|
||||||
|
/// // ...
|
||||||
|
///
|
||||||
|
/// if condition {
|
||||||
|
/// ErasedJson::new(&foo)
|
||||||
|
/// } else {
|
||||||
|
/// ErasedJson::new(&bar)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ErasedJson(serde_json::Result<Vec<u8>>);
|
||||||
|
|
||||||
|
impl ErasedJson {
|
||||||
|
/// Create an `ErasedJson` by serializing a value.
|
||||||
|
pub fn new<T: Serialize>(val: T) -> Self {
|
||||||
|
Self(serde_json::to_vec(&val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for ErasedJson {
|
||||||
|
type Body = Full<Bytes>;
|
||||||
|
type BodyError = Infallible;
|
||||||
|
|
||||||
|
fn into_response(self) -> Response<Self::Body> {
|
||||||
|
#[allow(clippy::declare_interior_mutable_const)]
|
||||||
|
const APPLICATION_JSON: HeaderValue = HeaderValue::from_static("application/json");
|
||||||
|
|
||||||
|
let bytes = match self.0 {
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(err) => {
|
||||||
|
return Response::builder()
|
||||||
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||||
|
.header(header::CONTENT_TYPE, "text/plain")
|
||||||
|
.body(Full::from(err.to_string()))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut res = Response::new(Full::from(bytes));
|
||||||
|
res.headers_mut()
|
||||||
|
.insert(header::CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
//! Additional types for generating responses.
|
||||||
|
|
||||||
|
#[cfg(feature = "erased-json")]
|
||||||
|
mod erased_json;
|
||||||
|
|
||||||
|
#[cfg(feature = "erased-json")]
|
||||||
|
pub use erased_json::ErasedJson;
|
||||||
+1
-1
@@ -45,7 +45,7 @@ base64 = { optional = true, version = "0.13" }
|
|||||||
headers = { optional = true, version = "0.3" }
|
headers = { optional = true, version = "0.3" }
|
||||||
mime = { optional = true, version = "0.3" }
|
mime = { optional = true, version = "0.3" }
|
||||||
multer = { optional = true, version = "2.0.0" }
|
multer = { optional = true, version = "2.0.0" }
|
||||||
serde_json = { version = "1.0", optional = true }
|
serde_json = { version = "1.0", optional = true, features = ["raw_value"] }
|
||||||
sha-1 = { optional = true, version = "0.9.6" }
|
sha-1 = { optional = true, version = "0.9.6" }
|
||||||
tokio-tungstenite = { optional = true, version = "0.16" }
|
tokio-tungstenite = { optional = true, version = "0.16" }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user