uv_distribution/
download.rs1use std::path::Path;
2
3use uv_cache_info::CacheInfo;
4use uv_distribution_filename::WheelFilename;
5use uv_distribution_types::{BuildInfo, BuiltDist, CachedDist, Dist, Hashed};
6use uv_metadata::{find_flat_dist_info, read_flat_wheel_metadata, read_wheel_variant};
7use uv_preview::PreviewFeature;
8use uv_pypi_types::{HashDigest, HashDigests, ResolutionMetadata};
9
10use crate::Error;
11
12pub fn check_supported_wheel_variant(dist: &BuiltDist) -> Result<(), Error> {
14 let filename = dist.wheel_filename();
15 if filename.variant().is_some()
16 && (dist.index().is_none() || !uv_preview::is_enabled(PreviewFeature::WheelVariants))
17 {
18 return Err(Error::UnsupportedWheelVariant(Box::new(filename.clone())));
19 }
20 Ok(())
21}
22
23pub(crate) fn variant_compatible(filename: &WheelFilename, archive: &Path) -> Result<bool, Error> {
25 let Some(label) = filename.variant() else {
26 return Ok(true);
27 };
28 if !uv_preview::is_enabled(PreviewFeature::WheelVariants) {
29 return Ok(false);
30 }
31
32 let dist_info = find_flat_dist_info(filename, archive)
33 .map_err(|err| Error::WheelMetadata(archive.to_path_buf(), Box::new(err)))?;
34 let path = archive.join(format!("{dist_info}.dist-info/variant.json"));
35 let metadata = read_wheel_variant(&path, label)
36 .map_err(|err| Error::WheelMetadata(path, Box::new(err)))?;
37 Ok(metadata
38 .score_variant(label, &metadata.static_supported_properties())
39 .is_some())
40}
41
42#[derive(Debug, Clone)]
44pub struct LocalWheel {
45 pub(crate) dist: Dist,
47 pub(crate) filename: WheelFilename,
49 pub(crate) archive: Box<Path>,
52 pub(crate) cache: CacheInfo,
54 pub(crate) build: Option<BuildInfo>,
56 pub(crate) hashes: HashDigests,
58}
59
60impl LocalWheel {
61 fn remote(&self) -> &Dist {
63 &self.dist
64 }
65
66 pub(crate) fn metadata(&self) -> Result<ResolutionMetadata, Error> {
68 read_flat_wheel_metadata(&self.filename, &self.archive)
69 .map_err(|err| Error::WheelMetadata(self.archive.to_path_buf(), Box::new(err)))
70 }
71}
72
73impl Hashed for LocalWheel {
74 fn hashes(&self) -> &[HashDigest] {
75 self.hashes.as_slice()
76 }
77}
78
79impl From<LocalWheel> for CachedDist {
81 fn from(wheel: LocalWheel) -> Self {
82 Self::from_remote(
83 wheel.dist,
84 wheel.filename,
85 wheel.hashes,
86 wheel.cache,
87 wheel.build,
88 wheel.archive,
89 )
90 }
91}
92
93impl std::fmt::Display for LocalWheel {
94 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 write!(f, "{}", self.remote())
96 }
97}