mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-28 02:40:11 +00:00
Add rkyv implementation for Core Metadata (#15532)
## Summary Enables us to store Core Metadata in zero-copy format.
This commit is contained in:
parent
615e076beb
commit
b2c8f5ef68
8 changed files with 94 additions and 4 deletions
|
|
@ -97,8 +97,21 @@ impl Default for DefaultExtras {
|
|||
/// See:
|
||||
/// - <https://peps.python.org/pep-0685/#specification/>
|
||||
/// - <https://packaging.python.org/en/latest/specifications/name-normalization/>
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)]
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Hash,
|
||||
Serialize,
|
||||
rkyv::Archive,
|
||||
rkyv::Deserialize,
|
||||
rkyv::Serialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[rkyv(derive(Debug))]
|
||||
pub struct ExtraName(SmallString);
|
||||
|
||||
impl ExtraName {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,20 @@ use crate::{
|
|||
/// See:
|
||||
/// - <https://peps.python.org/pep-0735/>
|
||||
/// - <https://packaging.python.org/en/latest/specifications/name-normalization/>
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(
|
||||
Debug,
|
||||
Clone,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Hash,
|
||||
rkyv::Archive,
|
||||
rkyv::Deserialize,
|
||||
rkyv::Serialize,
|
||||
)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[rkyv(derive(Debug))]
|
||||
pub struct GroupName(SmallString);
|
||||
|
||||
impl GroupName {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ boxcar = { workspace = true }
|
|||
indexmap = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
rkyv = { workspace = true, optional = true }
|
||||
rustc-hash = { workspace = true }
|
||||
schemars = { workspace = true, optional = true }
|
||||
serde = { workspace = true, features = ["derive", "rc"] }
|
||||
|
|
@ -56,5 +57,6 @@ schemars = ["dep:schemars"]
|
|||
# be supported.
|
||||
non-pep508-extensions = []
|
||||
default = []
|
||||
rkyv = ["dep:rkyv"]
|
||||
# Match the API of the published crate, for compatibility.
|
||||
serde = []
|
||||
|
|
|
|||
|
|
@ -1045,6 +1045,41 @@ fn parse_pep508_requirement<T: Pep508Url>(
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "rkyv")]
|
||||
/// An [`rkyv`] implementation for [`Requirement`].
|
||||
impl<T: Pep508Url + Display> rkyv::Archive for Requirement<T> {
|
||||
type Archived = rkyv::string::ArchivedString;
|
||||
type Resolver = rkyv::string::StringResolver;
|
||||
|
||||
#[inline]
|
||||
fn resolve(&self, resolver: Self::Resolver, out: rkyv::Place<Self::Archived>) {
|
||||
let as_str = self.to_string();
|
||||
rkyv::string::ArchivedString::resolve_from_str(&as_str, resolver, out);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rkyv")]
|
||||
impl<T: Pep508Url + Display, S> rkyv::Serialize<S> for Requirement<T>
|
||||
where
|
||||
S: rkyv::rancor::Fallible + rkyv::ser::Allocator + rkyv::ser::Writer + ?Sized,
|
||||
S::Error: rkyv::rancor::Source,
|
||||
{
|
||||
fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
|
||||
let as_str = self.to_string();
|
||||
rkyv::string::ArchivedString::serialize_from_str(&as_str, serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rkyv")]
|
||||
impl<T: Pep508Url + Display, D: rkyv::rancor::Fallible + ?Sized>
|
||||
rkyv::Deserialize<Requirement<T>, D> for rkyv::string::ArchivedString
|
||||
{
|
||||
fn deserialize(&self, _deserializer: &mut D) -> Result<Requirement<T>, D::Error> {
|
||||
// SAFETY: We only serialize valid requirements.
|
||||
Ok(Requirement::<T>::from_str(self.as_str()).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
//! Half of these tests are copied from <https://github.com/pypa/packaging/pull/624>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ uv-distribution-filename = { workspace = true }
|
|||
uv-git-types = { workspace = true }
|
||||
uv-normalize = { workspace = true }
|
||||
uv-pep440 = { workspace = true }
|
||||
uv-pep508 = { workspace = true }
|
||||
uv-pep508 = { workspace = true, features = ["rkyv"] }
|
||||
uv-redacted = { workspace = true }
|
||||
uv-small-str = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,11 @@ use crate::{LenientVersionSpecifiers, MetadataError, VerbatimParsedUrl, metadata
|
|||
/// fields that are relevant to dependency resolution.
|
||||
///
|
||||
/// Core Metadata 2.3 is specified in <https://packaging.python.org/specifications/core-metadata/>.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(
|
||||
Serialize, Deserialize, Debug, Clone, rkyv::Archive, rkyv::Deserialize, rkyv::Serialize,
|
||||
)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[rkyv(derive(Debug))]
|
||||
pub struct ResolutionMetadata {
|
||||
// Mandatory fields
|
||||
pub name: PackageName,
|
||||
|
|
|
|||
|
|
@ -141,6 +141,18 @@ impl<'de> Deserialize<'de> for CoreMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
impl Serialize for CoreMetadata {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
Self::Bool(is_available) => serializer.serialize_bool(*is_available),
|
||||
Self::Hashes(hashes) => hashes.serialize(serializer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CoreMetadata {
|
||||
pub fn is_available(&self) -> bool {
|
||||
match self {
|
||||
|
|
@ -169,6 +181,18 @@ impl<'de> Deserialize<'de> for Yanked {
|
|||
}
|
||||
}
|
||||
|
||||
impl Serialize for Yanked {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
match self {
|
||||
Self::Bool(is_yanked) => serializer.serialize_bool(*is_yanked),
|
||||
Self::Reason(reason) => serializer.serialize_str(reason.as_ref()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Yanked {
|
||||
pub fn is_yanked(&self) -> bool {
|
||||
match self {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue