mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-22 00:00:17 +02:00
Further downstream code size improvements (#3300)
This commit is contained in:
@@ -162,27 +162,30 @@ where
|
||||
type Rejection = PathRejection;
|
||||
|
||||
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
|
||||
let params = match parts.extensions.get::<UrlParams>() {
|
||||
Some(UrlParams::Params(params)) => params,
|
||||
Some(UrlParams::InvalidUtf8InPathParam { key }) => {
|
||||
let err = PathDeserializationError {
|
||||
kind: ErrorKind::InvalidUtf8InPathParam {
|
||||
key: key.to_string(),
|
||||
},
|
||||
};
|
||||
let err = FailedToDeserializePathParams(err);
|
||||
return Err(err.into());
|
||||
// Extracted into separate fn so it's only compiled once for all T.
|
||||
fn get_params(parts: &Parts) -> Result<&[(Arc<str>, PercentDecodedStr)], PathRejection> {
|
||||
match parts.extensions.get::<UrlParams>() {
|
||||
Some(UrlParams::Params(params)) => Ok(params),
|
||||
Some(UrlParams::InvalidUtf8InPathParam { key }) => {
|
||||
let err = PathDeserializationError {
|
||||
kind: ErrorKind::InvalidUtf8InPathParam {
|
||||
key: key.to_string(),
|
||||
},
|
||||
};
|
||||
Err(FailedToDeserializePathParams(err).into())
|
||||
}
|
||||
None => Err(MissingPathParams.into()),
|
||||
}
|
||||
None => {
|
||||
return Err(MissingPathParams.into());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
T::deserialize(de::PathDeserializer::new(params))
|
||||
.map_err(|err| {
|
||||
PathRejection::FailedToDeserializePathParams(FailedToDeserializePathParams(err))
|
||||
})
|
||||
.map(Path)
|
||||
fn failed_to_deserialize_path_params(err: PathDeserializationError) -> PathRejection {
|
||||
PathRejection::FailedToDeserializePathParams(FailedToDeserializePathParams(err))
|
||||
}
|
||||
|
||||
match T::deserialize(de::PathDeserializer::new(get_params(parts)?)) {
|
||||
Ok(val) => Ok(Path(val)),
|
||||
Err(e) => Err(failed_to_deserialize_path_params(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-8
@@ -110,17 +110,21 @@ where
|
||||
T: Serialize,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
match serde_urlencoded::to_string(&self.0) {
|
||||
Ok(body) => (
|
||||
[(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())],
|
||||
body,
|
||||
)
|
||||
.into_response(),
|
||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response(),
|
||||
// Extracted into separate fn so it's only compiled once for all T.
|
||||
fn make_response(ser_result: Result<String, serde_urlencoded::ser::Error>) -> Response {
|
||||
match ser_result {
|
||||
Ok(body) => (
|
||||
[(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())],
|
||||
body,
|
||||
)
|
||||
.into_response(),
|
||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
make_response(serde_urlencoded::to_string(&self.0))
|
||||
}
|
||||
}
|
||||
|
||||
axum_core::__impl_deref!(Form);
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+46
-40
@@ -176,31 +176,31 @@ where
|
||||
/// 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 => {
|
||||
// Extracted into separate fn so it's only compiled once for all T.
|
||||
fn make_rejection(err: serde_path_to_error::Error<serde_json::Error>) -> JsonRejection {
|
||||
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()
|
||||
}
|
||||
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))
|
||||
let deserializer = &mut serde_json::Deserializer::from_slice(bytes);
|
||||
|
||||
match serde_path_to_error::deserialize(deserializer) {
|
||||
Ok(value) => Ok(Json(value)),
|
||||
Err(err) => Err(make_rejection(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,28 +209,34 @@ where
|
||||
T: Serialize,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
// Extracted into separate fn so it's only compiled once for all T.
|
||||
fn make_response(buf: BytesMut, ser_result: serde_json::Result<()>) -> Response {
|
||||
match ser_result {
|
||||
Ok(()) => (
|
||||
[(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static(mime::APPLICATION_JSON.as_ref()),
|
||||
)],
|
||||
buf.freeze(),
|
||||
)
|
||||
.into_response(),
|
||||
Err(err) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
[(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),
|
||||
)],
|
||||
err.to_string(),
|
||||
)
|
||||
.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
// Use a small initial capacity of 128 bytes like serde_json::to_vec
|
||||
// https://docs.rs/serde_json/1.0.82/src/serde_json/ser.rs.html#2189
|
||||
let mut buf = BytesMut::with_capacity(128).writer();
|
||||
match serde_json::to_writer(&mut buf, &self.0) {
|
||||
Ok(()) => (
|
||||
[(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static(mime::APPLICATION_JSON.as_ref()),
|
||||
)],
|
||||
buf.into_inner().freeze(),
|
||||
)
|
||||
.into_response(),
|
||||
Err(err) => (
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
[(
|
||||
header::CONTENT_TYPE,
|
||||
HeaderValue::from_static(mime::TEXT_PLAIN_UTF_8.as_ref()),
|
||||
)],
|
||||
err.to_string(),
|
||||
)
|
||||
.into_response(),
|
||||
}
|
||||
let res = serde_json::to_writer(&mut buf, &self.0);
|
||||
make_response(buf.into_inner(), res)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user