mirror of
https://github.com/tokio-rs/axum.git
synced 2024-12-28 07:20:12 +01:00
Json: add from_bytes method, use that in 'impl FromRequest' (#2244)
Signed-off-by: wayne warren <wayne.warren.s@gmail.com> Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
This commit is contained in:
parent
c100650464
commit
0c7ff7c76b
2 changed files with 39 additions and 25 deletions
|
@ -66,6 +66,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- **added:** Implement `IntoResponse` for `(R,) where R: IntoResponse` ([#2143])
|
||||
- **changed:** For SSE, add space between field and value for compatibility ([#2149])
|
||||
- **added:** Add `NestedPath` extractor ([#1924])
|
||||
- **added:** Add `axum::Json::from_bytes` ([#2244])
|
||||
|
||||
[#1664]: https://github.com/tokio-rs/axum/pull/1664
|
||||
[#1751]: https://github.com/tokio-rs/axum/pull/1751
|
||||
|
@ -86,6 +87,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
[#2140]: https://github.com/tokio-rs/axum/pull/2140
|
||||
[#2143]: https://github.com/tokio-rs/axum/pull/2143
|
||||
[#2149]: https://github.com/tokio-rs/axum/pull/2149
|
||||
[#2244]: https://github.com/tokio-rs/axum/pull/2244
|
||||
|
||||
# 0.6.17 (25. April, 2023)
|
||||
|
||||
|
|
|
@ -103,31 +103,7 @@ where
|
|||
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
||||
if json_content_type(req.headers()) {
|
||||
let bytes = Bytes::from_request(req, state).await?;
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(&bytes);
|
||||
|
||||
let value = match serde_path_to_error::deserialize(deserializer) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
let rejection = match err.inner().classify() {
|
||||
serde_json::error::Category::Data => JsonDataError::from_err(err).into(),
|
||||
serde_json::error::Category::Syntax | serde_json::error::Category::Eof => {
|
||||
JsonSyntaxError::from_err(err).into()
|
||||
}
|
||||
serde_json::error::Category::Io => {
|
||||
if cfg!(debug_assertions) {
|
||||
// we don't use `serde_json::from_reader` and instead always buffer
|
||||
// bodies first, so we shouldn't encounter any IO errors
|
||||
unreachable!()
|
||||
} else {
|
||||
JsonSyntaxError::from_err(err).into()
|
||||
}
|
||||
}
|
||||
};
|
||||
return Err(rejection);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Json(value))
|
||||
Self::from_bytes(&bytes)
|
||||
} else {
|
||||
Err(MissingJsonContentType.into())
|
||||
}
|
||||
|
@ -167,6 +143,42 @@ impl<T> From<T> for Json<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Json<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
/// Construct a `Json<T>` from a byte slice. Most users should prefer to use the `FromRequest` impl
|
||||
/// but special cases may require first extracting a `Request` into `Bytes` then optionally
|
||||
/// constructing a `Json<T>`.
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, JsonRejection> {
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(bytes);
|
||||
|
||||
let value = match serde_path_to_error::deserialize(deserializer) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
let rejection = match err.inner().classify() {
|
||||
serde_json::error::Category::Data => JsonDataError::from_err(err).into(),
|
||||
serde_json::error::Category::Syntax | serde_json::error::Category::Eof => {
|
||||
JsonSyntaxError::from_err(err).into()
|
||||
}
|
||||
serde_json::error::Category::Io => {
|
||||
if cfg!(debug_assertions) {
|
||||
// we don't use `serde_json::from_reader` and instead always buffer
|
||||
// bodies first, so we shouldn't encounter any IO errors
|
||||
unreachable!()
|
||||
} else {
|
||||
JsonSyntaxError::from_err(err).into()
|
||||
}
|
||||
}
|
||||
};
|
||||
return Err(rejection);
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Json(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoResponse for Json<T>
|
||||
where
|
||||
T: Serialize,
|
||||
|
|
Loading…
Reference in a new issue