Optimize deserialization of Path (#2679)

This commit is contained in:
dakai-chen
2024-03-27 08:51:48 +01:00
committed by GitHub
parent 6bd6556385
commit ae8c43765d
3 changed files with 19 additions and 31 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
# Unreleased # Unreleased
- None. - **change:** Avoid cloning `Arc` during deserialization of `Path`
# 0.7.5 (24. March, 2024) # 0.7.5 (24. March, 2024)
+18 -26
View File
@@ -210,14 +210,14 @@ impl<'de> Deserializer<'de> for PathDeserializer<'de> {
} }
visitor.visit_enum(EnumDeserializer { visitor.visit_enum(EnumDeserializer {
value: self.url_params[0].1.clone().into_inner(), value: &self.url_params[0].1,
}) })
} }
} }
struct MapDeserializer<'de> { struct MapDeserializer<'de> {
params: &'de [(Arc<str>, PercentDecodedStr)], params: &'de [(Arc<str>, PercentDecodedStr)],
key: Option<KeyOrIdx>, key: Option<KeyOrIdx<'de>>,
value: Option<&'de PercentDecodedStr>, value: Option<&'de PercentDecodedStr>,
} }
@@ -232,11 +232,8 @@ impl<'de> MapAccess<'de> for MapDeserializer<'de> {
Some(((key, value), tail)) => { Some(((key, value), tail)) => {
self.value = Some(value); self.value = Some(value);
self.params = tail; self.params = tail;
self.key = Some(KeyOrIdx::Key(key.clone())); self.key = Some(KeyOrIdx::Key(key));
seed.deserialize(KeyDeserializer { seed.deserialize(KeyDeserializer { key }).map(Some)
key: Arc::clone(key),
})
.map(Some)
} }
None => Ok(None), None => Ok(None),
} }
@@ -256,8 +253,8 @@ impl<'de> MapAccess<'de> for MapDeserializer<'de> {
} }
} }
struct KeyDeserializer { struct KeyDeserializer<'de> {
key: Arc<str>, key: &'de str,
} }
macro_rules! parse_key { 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; type Error = PathDeserializationError;
parse_key!(deserialize_identifier); parse_key!(deserialize_identifier);
@@ -302,7 +299,7 @@ macro_rules! parse_value {
if let Some(key) = self.key.take() { if let Some(key) = self.key.take() {
let kind = match key { let kind = match key {
KeyOrIdx::Key(key) => ErrorKind::ParseErrorAtKey { KeyOrIdx::Key(key) => ErrorKind::ParseErrorAtKey {
key: key.to_string(), key: key.to_owned(),
value: self.value.as_str().to_owned(), value: self.value.as_str().to_owned(),
expected_type: $ty, expected_type: $ty,
}, },
@@ -327,7 +324,7 @@ macro_rules! parse_value {
#[derive(Debug)] #[derive(Debug)]
struct ValueDeserializer<'de> { struct ValueDeserializer<'de> {
key: Option<KeyOrIdx>, key: Option<KeyOrIdx<'de>>,
value: &'de PercentDecodedStr, value: &'de PercentDecodedStr,
} }
@@ -416,7 +413,7 @@ impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
V: Visitor<'de>, V: Visitor<'de>,
{ {
struct PairDeserializer<'de> { struct PairDeserializer<'de> {
key: Option<KeyOrIdx>, key: Option<KeyOrIdx<'de>>,
value: Option<&'de PercentDecodedStr>, value: Option<&'de PercentDecodedStr>,
} }
@@ -507,9 +504,7 @@ impl<'de> Deserializer<'de> for ValueDeserializer<'de> {
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
visitor.visit_enum(EnumDeserializer { visitor.visit_enum(EnumDeserializer { value: self.value })
value: self.value.clone().into_inner(),
})
} }
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> 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 { struct EnumDeserializer<'de> {
value: Arc<str>, value: &'de str,
} }
impl<'de> EnumAccess<'de> for EnumDeserializer { impl<'de> EnumAccess<'de> for EnumDeserializer<'de> {
type Error = PathDeserializationError; type Error = PathDeserializationError;
type Variant = UnitVariant; type Variant = UnitVariant;
@@ -598,10 +593,7 @@ impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
let idx = self.idx; let idx = self.idx;
self.idx += 1; self.idx += 1;
Ok(Some(seed.deserialize(ValueDeserializer { Ok(Some(seed.deserialize(ValueDeserializer {
key: Some(KeyOrIdx::Idx { key: Some(KeyOrIdx::Idx { idx, key }),
idx,
key: key.clone(),
}),
value, value,
})?)) })?))
} }
@@ -611,9 +603,9 @@ impl<'de> SeqAccess<'de> for SeqDeserializer<'de> {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum KeyOrIdx { enum KeyOrIdx<'de> {
Key(Arc<str>), Key(&'de str),
Idx { idx: usize, key: Arc<str> }, Idx { idx: usize, key: &'de str },
} }
#[cfg(test)] #[cfg(test)]
-4
View File
@@ -20,10 +20,6 @@ impl PercentDecodedStr {
pub(crate) fn as_str(&self) -> &str { pub(crate) fn as_str(&self) -> &str {
&self.0 &self.0
} }
pub(crate) fn into_inner(self) -> Arc<str> {
self.0
}
} }
impl Deref for PercentDecodedStr { impl Deref for PercentDecodedStr {