summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakai-chen <dakai.chen@outlook.com>2024-03-27 15:51:48 +0800
committerGitHub <noreply@github.com>2024-03-27 08:51:48 +0100
commitae8c43765df0d831d27d6d849d18d2f38e6b7461 (patch)
treefd131f2e4dfc5ccdafad836d7c8671bb2ebf99d2
parent6bd6556385c7f6bf1ee7ea64e3a8fbe2076a1506 (diff)
Optimize deserialization of Path (#2679)
-rw-r--r--axum/CHANGELOG.md2
-rw-r--r--axum/src/extract/path/de.rs44
-rw-r--r--axum/src/util.rs4
3 files changed, 19 insertions, 31 deletions
diff --git a/axum/CHANGELOG.md b/axum/CHANGELOG.md
index caf41764..220c458e 100644
--- a/axum/CHANGELOG.md
+++ b/axum/CHANGELOG.md
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased
-- None.
+- **change:** Avoid cloning `Arc` during deserialization of `Path`
# 0.7.5 (24. March, 2024)
diff --git a/axum/src/extract/path/de.rs b/axum/src/extract/path/de.rs
index bbc0c85c..8ba8a431 100644
--- a/axum/src/extract/path/de.rs
+++ b/axum/src/extract/path/de.rs
@@ -210,14 +210,14 @@ impl<'de> Deserializer<'de> for PathDeserializer<'de> {
}
visitor.visit_enum(EnumDeserializer {
- value: self.url_params[0].1.clone().into_inner(),
+ value: &self.url_params[0].1,
})
}
}
struct MapDeserializer<'de> {
params: &'de [(Arc<str>, PercentDecodedStr)],
- key: Option<KeyOrIdx>,
+ key: Option<KeyOrIdx<'de>>,
value: Option<&'de PercentDecodedStr>,
}
@@ -232,11 +232,8 @@ impl<'de> MapAccess<'de> for MapDeserializer<'de> {
Some(((key, value), tail)) => {
self.value = Some(value);
self.params = tail;
- self.key = Some(KeyOrIdx::Key(key.clone()));
- seed.deserialize(KeyDeserializer {
- key: Arc::clone(key),
- })
- .map(Some)
+ self.key = Some(KeyOrIdx::Key(key));
+ seed.deserialize(KeyDeserializer { key }).map(Some)
}
None => Ok(None),
}
@@ -256,8 +253,8 @@ impl<'de> MapAccess<'de> for MapDeserializer<'de> {
}
}
-struct KeyDeserializer {
- key: Arc<str>,
+struct KeyDeserializer<'de> {
+ key: &'de str,
}
macro_rules! parse_key {
@@ -271,7 +268,7 @@ macro_rules! parse_key {
};
}
-impl<'de> Deserializer<'de> for KeyDeserializer {
+impl<'de> Deserializer<'de> for KeyDeserializer<'de> {
type Error = PathDeserializationError;
parse_key!(deserialize_identifier);
@@ -302,7 +299,7 @@ macro_rules! parse_value {
if let Some(key) = self.key.take() {
let kind = match key {
KeyOrIdx::Key(key) => ErrorKind::ParseErrorAtKey {
- key: key.to_string(),
+ key: key.to_owned(),
value: self.value.as_str().to_owned(),
expected_type: $ty,
},
@@ -327,7 +324,7 @@ macro_rules! parse_value {
#[derive(Debug)]
struct ValueDeserializer<'de> {
- key: Option<KeyOrIdx>,
+ key: Option<KeyOrIdx<'de>>,
value: &'de PercentDecodedStr,
}
@@ -416,7 +413,7 @@ impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
V: Visitor<'de>,
{
struct PairDeserializer<'de> {
- key: Option<KeyOrIdx>,
+ key: Option<KeyOrIdx<'de>>,
value: Option<&'de PercentDecodedStr>,
}
@@ -507,9 +504,7 @@ impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
where
V: Visitor<'de>,
{
- visitor.visit_enum(EnumDeserializer {
- value: self.value.clone().into_inner(),
- })
+ visitor.visit_enum(EnumDeserializer { value: self.value })
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -520,11 +515,11 @@ impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
}
}
-struct EnumDeserializer {
- value: Arc<str>,
+struct EnumDeserializer<'de> {
+ value: &'de str,
}
-impl<'de> EnumAccess<'de> for EnumDeserializer {
+impl<'de> EnumAccess<'de> for EnumDeserializer<'de> {
type Error = PathDeserializationError;
type Variant = UnitVariant;
@@ -598,10 +593,7 @@ impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
let idx = self.idx;
self.idx += 1;
Ok(Some(seed.deserialize(ValueDeserializer {
- key: Some(KeyOrIdx::Idx {
- idx,
- key: key.clone(),
- }),
+ key: Some(KeyOrIdx::Idx { idx, key }),
value,
})?))
}
@@ -611,9 +603,9 @@ impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
}
#[derive(Debug, Clone)]
-enum KeyOrIdx {
- Key(Arc<str>),
- Idx { idx: usize, key: Arc<str> },
+enum KeyOrIdx<'de> {
+ Key(&'de str),
+ Idx { idx: usize, key: &'de str },
}
#[cfg(test)]
diff --git a/axum/src/util.rs b/axum/src/util.rs
index 60abe38b..bae803db 100644
--- a/axum/src/util.rs
+++ b/axum/src/util.rs
@@ -20,10 +20,6 @@ impl PercentDecodedStr {
pub(crate) fn as_str(&self) -> &str {
&self.0
}
-
- pub(crate) fn into_inner(self) -> Arc<str> {
- self.0
- }
}
impl Deref for PercentDecodedStr {