use std::path::Path;
use uv_cache_info::CacheInfo;
use uv_distribution_filename::WheelFilename;
use uv_distribution_types::{BuildInfo, BuiltDist, CachedDist, Dist, Hashed};
use uv_metadata::{find_flat_dist_info, read_flat_wheel_metadata, read_wheel_variant};
use uv_preview::PreviewFeature;
use uv_pypi_types::{HashDigest, HashDigests, ResolutionMetadata};
use crate::Error;
pub fn check_supported_wheel_variant(dist: &BuiltDist) -> Result<(), Error> {
let filename = dist.wheel_filename();
if filename.variant().is_some()
&& (dist.index().is_none() || !uv_preview::is_enabled(PreviewFeature::WheelVariants))
{
return Err(Error::UnsupportedWheelVariant(Box::new(filename.clone())));
}
Ok(())
}
pub(crate) fn variant_compatible(filename: &WheelFilename, archive: &Path) -> Result<bool, Error> {
let Some(label) = filename.variant() else {
return Ok(true);
};
if !uv_preview::is_enabled(PreviewFeature::WheelVariants) {
return Ok(false);
}
let dist_info = find_flat_dist_info(filename, archive)
.map_err(|err| Error::WheelMetadata(archive.to_path_buf(), Box::new(err)))?;
let path = archive.join(format!("{dist_info}.dist-info/variant.json"));
let metadata = read_wheel_variant(&path, label)
.map_err(|err| Error::WheelMetadata(path, Box::new(err)))?;
Ok(metadata
.score_variant(label, &metadata.static_supported_properties())
.is_some())
}
#[derive(Debug, Clone)]
pub struct LocalWheel {
pub(crate) dist: Dist,
pub(crate) filename: WheelFilename,
pub(crate) archive: Box<Path>,
pub(crate) cache: CacheInfo,
pub(crate) build: Option<BuildInfo>,
pub(crate) hashes: HashDigests,
}
impl LocalWheel {
fn remote(&self) -> &Dist {
&self.dist
}
pub(crate) fn metadata(&self) -> Result<ResolutionMetadata, Error> {
read_flat_wheel_metadata(&self.filename, &self.archive)
.map_err(|err| Error::WheelMetadata(self.archive.to_path_buf(), Box::new(err)))
}
}
impl Hashed for LocalWheel {
fn hashes(&self) -> &[HashDigest] {
self.hashes.as_slice()
}
}
impl From<LocalWheel> for CachedDist {
fn from(wheel: LocalWheel) -> Self {
Self::from_remote(
wheel.dist,
wheel.filename,
wheel.hashes,
wheel.cache,
wheel.build,
wheel.archive,
)
}
}
impl std::fmt::Display for LocalWheel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.remote())
}
}