uv_distribution_types/
id.rs

1use std::fmt::{Display, Formatter};
2use std::path::PathBuf;
3
4use uv_cache_key::{CanonicalUrl, RepositoryUrl};
5
6use uv_normalize::PackageName;
7use uv_pep440::Version;
8use uv_pypi_types::HashDigest;
9use uv_redacted::DisplaySafeUrl;
10
11/// A unique identifier for a package. A package can either be identified by a name (e.g., `black`)
12/// or a URL (e.g., `git+https://github.com/psf/black`).
13#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
14pub enum PackageId {
15    /// The identifier consists of a package name.
16    Name(PackageName),
17    /// The identifier consists of a URL.
18    Url(CanonicalUrl),
19}
20
21impl PackageId {
22    /// Create a new [`PackageId`] from a package name and version.
23    pub fn from_registry(name: PackageName) -> Self {
24        Self::Name(name)
25    }
26
27    /// Create a new [`PackageId`] from a URL.
28    pub fn from_url(url: &DisplaySafeUrl) -> Self {
29        Self::Url(CanonicalUrl::new(url))
30    }
31}
32
33impl Display for PackageId {
34    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35        match self {
36            Self::Name(name) => write!(f, "{name}"),
37            Self::Url(url) => write!(f, "{url}"),
38        }
39    }
40}
41
42/// A unique identifier for a package at a specific version (e.g., `black==23.10.0`).
43#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
44pub enum VersionId {
45    /// The identifier consists of a package name and version.
46    NameVersion(PackageName, Version),
47    /// The identifier consists of a URL.
48    Url(CanonicalUrl),
49}
50
51impl VersionId {
52    /// Create a new [`VersionId`] from a package name and version.
53    pub fn from_registry(name: PackageName, version: Version) -> Self {
54        Self::NameVersion(name, version)
55    }
56
57    /// Create a new [`VersionId`] from a URL.
58    pub fn from_url(url: &DisplaySafeUrl) -> Self {
59        Self::Url(CanonicalUrl::new(url))
60    }
61}
62
63impl Display for VersionId {
64    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
65        match self {
66            Self::NameVersion(name, version) => write!(f, "{name}-{version}"),
67            Self::Url(url) => write!(f, "{url}"),
68        }
69    }
70}
71
72/// A unique resource identifier for the distribution, like a SHA-256 hash of the distribution's
73/// contents.
74///
75/// A distribution is a specific archive of a package at a specific version. For a given package
76/// version, there may be multiple distributions, e.g., source distribution, along with
77/// multiple binary distributions (wheels) for different platforms. As a concrete example,
78/// `black-23.10.0-py3-none-any.whl` would represent a (binary) distribution of the `black` package
79/// at version `23.10.0`.
80///
81/// The distribution ID is used to uniquely identify a distribution. Ideally, the distribution
82/// ID should be a hash of the distribution's contents, though in practice, it's only required
83/// that the ID is unique within a single invocation of the resolver (and so, e.g., a hash of
84/// the URL would also be sufficient).
85#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
86pub enum DistributionId {
87    Url(CanonicalUrl),
88    PathBuf(PathBuf),
89    Digest(HashDigest),
90    AbsoluteUrl(String),
91    RelativeUrl(String, String),
92}
93
94/// A unique identifier for a resource, like a URL or a Git repository.
95#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
96pub enum ResourceId {
97    Url(RepositoryUrl),
98    PathBuf(PathBuf),
99    Digest(HashDigest),
100    AbsoluteUrl(String),
101    RelativeUrl(String, String),
102}
103
104impl From<&Self> for VersionId {
105    /// Required for `WaitMap::wait`.
106    fn from(value: &Self) -> Self {
107        value.clone()
108    }
109}
110
111impl From<&Self> for DistributionId {
112    /// Required for `WaitMap::wait`.
113    fn from(value: &Self) -> Self {
114        value.clone()
115    }
116}
117
118impl From<&Self> for ResourceId {
119    /// Required for `WaitMap::wait`.
120    fn from(value: &Self) -> Self {
121        value.clone()
122    }
123}