Replace PyPI-internal Hashes representation with flat vector (#2925)

## Summary

Right now, we have a `Hashes` representation that looks like:

```rust
/// A dictionary mapping a hash name to a hex encoded digest of the file.
///
/// PEP 691 says multiple hashes can be included and the interpretation is left to the client.
#[derive(Debug, Clone, Eq, PartialEq, Default, Deserialize)]
pub struct Hashes {
    pub md5: Option<Box<str>>,
    pub sha256: Option<Box<str>>,
    pub sha384: Option<Box<str>>,
    pub sha512: Option<Box<str>>,
}
```

It stems from the PyPI API, which returns a dictionary of hashes.

We tend to pass these around as a vector of `Vec<Hashes>`. But it's a
bit strange because each entry in that vector could contain multiple
hashes. And it makes it difficult to ask questions like "Is
`sha256:ab21378ca980a8` in the set of hashes"?

This PR instead treats `Hashes` as the PyPI-internal type, and uses a
new `Vec<HashDigest>` everywhere in our own APIs.
This commit is contained in:
Charlie Marsh 2024-04-09 12:56:16 -04:00 committed by GitHub
parent 1512e07a2e
commit 13ae5ac8dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 195 additions and 103 deletions

View file

@ -12,7 +12,7 @@ use distribution_types::{
};
use pep440_rs::{Version, VersionSpecifiers};
use platform_tags::Tags;
use pypi_types::{Hashes, Yanked};
use pypi_types::{HashDigest, Yanked};
use rkyv::{de::deserializers::SharedDeserializeMap, Deserialize};
use uv_client::{FlatDistributions, OwnedArchive, SimpleMetadata, VersionFiles};
use uv_configuration::{NoBinary, NoBuild};
@ -176,7 +176,7 @@ impl VersionMap {
}
/// Return the [`Hashes`] for the given version, if any.
pub(crate) fn hashes(&self, version: &Version) -> Option<Vec<Hashes>> {
pub(crate) fn hashes(&self, version: &Version) -> Option<Vec<HashDigest>> {
match self.inner {
VersionMapInner::Eager(ref map) => map.get(version).map(|file| file.hashes().to_vec()),
VersionMapInner::Lazy(ref lazy) => lazy.get(version).map(|file| file.hashes().to_vec()),
@ -378,7 +378,7 @@ impl VersionMapLazy {
let version = filename.version().clone();
let requires_python = file.requires_python.clone();
let yanked = file.yanked.clone();
let hash = file.hashes.clone();
let hashes = file.hashes.clone();
match filename {
DistFilename::WheelFilename(filename) => {
let compatibility = self.wheel_compatibility(
@ -394,7 +394,7 @@ impl VersionMapLazy {
file,
self.index.clone(),
);
priority_dist.insert_built(dist, Some(hash), compatibility);
priority_dist.insert_built(dist, hashes, compatibility);
}
DistFilename::SourceDistFilename(filename) => {
let compatibility = self.source_dist_compatibility(
@ -409,7 +409,7 @@ impl VersionMapLazy {
file,
self.index.clone(),
);
priority_dist.insert_source(dist, Some(hash), compatibility);
priority_dist.insert_source(dist, hashes, compatibility);
}
}
}