mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-04 19:08:04 +00:00
Avoid using owned String
in deserializers (#11764)
## Summary This is the pattern I see in a variety of crates, and I believe this is preferred if you don't _need_ an owned `String`, since you can avoid the allocation. This could be pretty impactful for us?
This commit is contained in:
parent
275db0668d
commit
c37af945b3
19 changed files with 350 additions and 104 deletions
|
@ -1,4 +1,5 @@
|
|||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::fmt::Formatter;
|
||||
use std::num::NonZero;
|
||||
use std::ops::Deref;
|
||||
use std::sync::LazyLock;
|
||||
|
@ -725,14 +726,26 @@ impl Version {
|
|||
}
|
||||
}
|
||||
|
||||
/// <https://github.com/serde-rs/serde/issues/1316#issue-332908452>
|
||||
impl<'de> Deserialize<'de> for Version {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
FromStr::from_str(&s).map_err(de::Error::custom)
|
||||
struct Visitor;
|
||||
|
||||
impl de::Visitor<'_> for Visitor {
|
||||
type Value = Version;
|
||||
|
||||
fn expecting(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
f.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||
Version::from_str(v).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt::Formatter;
|
||||
use std::ops::Bound;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -161,8 +162,21 @@ impl<'de> Deserialize<'de> for VersionSpecifiers {
|
|||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
Self::from_str(&s).map_err(de::Error::custom)
|
||||
struct Visitor;
|
||||
|
||||
impl de::Visitor<'_> for Visitor {
|
||||
type Value = VersionSpecifiers;
|
||||
|
||||
fn expecting(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
f.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||
VersionSpecifiers::from_str(v).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +186,7 @@ impl Serialize for VersionSpecifiers {
|
|||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.collect_str(
|
||||
serializer.serialize_str(
|
||||
&self
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
|
@ -256,14 +270,26 @@ pub struct VersionSpecifier {
|
|||
pub(crate) version: Version,
|
||||
}
|
||||
|
||||
/// <https://github.com/serde-rs/serde/issues/1316#issue-332908452>
|
||||
impl<'de> Deserialize<'de> for VersionSpecifier {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
FromStr::from_str(&s).map_err(de::Error::custom)
|
||||
struct Visitor;
|
||||
|
||||
impl de::Visitor<'_> for Visitor {
|
||||
type Value = VersionSpecifier;
|
||||
|
||||
fn expecting(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
f.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E: de::Error>(self, v: &str) -> Result<Self::Value, E> {
|
||||
VersionSpecifier::from_str(v).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.deserialize_str(Visitor)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue