uv_distribution_types/
cached.rs

1use std::path::Path;
2
3use uv_cache_info::CacheInfo;
4use uv_distribution_filename::WheelFilename;
5use uv_normalize::PackageName;
6use uv_pypi_types::{HashDigest, HashDigests, VerbatimParsedUrl};
7
8use crate::{
9    BuildInfo, BuiltDist, Dist, DistributionMetadata, Hashed, InstalledMetadata, InstalledVersion,
10    Name, ParsedUrl, SourceDist, VersionOrUrlRef,
11};
12
13/// A built distribution (wheel) that exists in the local cache.
14#[derive(Debug, Clone, Hash, PartialEq, Eq)]
15#[allow(clippy::large_enum_variant)]
16pub enum CachedDist {
17    /// The distribution exists in a registry, like `PyPI`.
18    Registry(CachedRegistryDist),
19    /// The distribution exists at an arbitrary URL.
20    Url(CachedDirectUrlDist),
21}
22
23#[derive(Debug, Clone, Hash, PartialEq, Eq)]
24pub struct CachedRegistryDist {
25    pub filename: WheelFilename,
26    pub path: Box<Path>,
27    pub hashes: HashDigests,
28    pub cache_info: CacheInfo,
29    pub build_info: Option<BuildInfo>,
30}
31
32#[derive(Debug, Clone, Hash, PartialEq, Eq)]
33pub struct CachedDirectUrlDist {
34    pub filename: WheelFilename,
35    pub url: VerbatimParsedUrl,
36    pub path: Box<Path>,
37    pub hashes: HashDigests,
38    pub cache_info: CacheInfo,
39    pub build_info: Option<BuildInfo>,
40}
41
42impl CachedDist {
43    /// Initialize a [`CachedDist`] from a [`Dist`].
44    pub fn from_remote(
45        remote: Dist,
46        filename: WheelFilename,
47        hashes: HashDigests,
48        cache_info: CacheInfo,
49        build_info: Option<BuildInfo>,
50        path: Box<Path>,
51    ) -> Self {
52        match remote {
53            Dist::Built(BuiltDist::Registry(_dist)) => Self::Registry(CachedRegistryDist {
54                filename,
55                path,
56                hashes,
57                cache_info,
58                build_info,
59            }),
60            Dist::Built(BuiltDist::DirectUrl(dist)) => Self::Url(CachedDirectUrlDist {
61                filename,
62                url: VerbatimParsedUrl {
63                    parsed_url: dist.parsed_url(),
64                    verbatim: dist.url,
65                },
66                hashes,
67                cache_info,
68                build_info,
69                path,
70            }),
71            Dist::Built(BuiltDist::Path(dist)) => Self::Url(CachedDirectUrlDist {
72                filename,
73                url: VerbatimParsedUrl {
74                    parsed_url: dist.parsed_url(),
75                    verbatim: dist.url,
76                },
77                hashes,
78                cache_info,
79                build_info,
80                path,
81            }),
82            Dist::Source(SourceDist::Registry(_dist)) => Self::Registry(CachedRegistryDist {
83                filename,
84                path,
85                hashes,
86                cache_info,
87                build_info,
88            }),
89            Dist::Source(SourceDist::DirectUrl(dist)) => Self::Url(CachedDirectUrlDist {
90                filename,
91                url: VerbatimParsedUrl {
92                    parsed_url: dist.parsed_url(),
93                    verbatim: dist.url,
94                },
95                hashes,
96                cache_info,
97                build_info,
98                path,
99            }),
100            Dist::Source(SourceDist::Git(dist)) => Self::Url(CachedDirectUrlDist {
101                filename,
102                url: VerbatimParsedUrl {
103                    parsed_url: dist.parsed_url(),
104                    verbatim: dist.url,
105                },
106                hashes,
107                cache_info,
108                build_info,
109                path,
110            }),
111            Dist::Source(SourceDist::Path(dist)) => Self::Url(CachedDirectUrlDist {
112                filename,
113                url: VerbatimParsedUrl {
114                    parsed_url: dist.parsed_url(),
115                    verbatim: dist.url,
116                },
117                hashes,
118                cache_info,
119                build_info,
120                path,
121            }),
122            Dist::Source(SourceDist::Directory(dist)) => Self::Url(CachedDirectUrlDist {
123                filename,
124                url: VerbatimParsedUrl {
125                    parsed_url: dist.parsed_url(),
126                    verbatim: dist.url,
127                },
128                hashes,
129                cache_info,
130                build_info,
131                path,
132            }),
133        }
134    }
135
136    /// Return the [`Path`] at which the distribution is stored on-disk.
137    pub fn path(&self) -> &Path {
138        match self {
139            Self::Registry(dist) => &dist.path,
140            Self::Url(dist) => &dist.path,
141        }
142    }
143
144    /// Return the [`CacheInfo`] of the distribution.
145    pub fn cache_info(&self) -> &CacheInfo {
146        match self {
147            Self::Registry(dist) => &dist.cache_info,
148            Self::Url(dist) => &dist.cache_info,
149        }
150    }
151
152    /// Return the [`BuildInfo`] of the distribution.
153    pub fn build_info(&self) -> Option<&BuildInfo> {
154        match self {
155            Self::Registry(dist) => dist.build_info.as_ref(),
156            Self::Url(dist) => dist.build_info.as_ref(),
157        }
158    }
159
160    /// Return the [`ParsedUrl`] of the distribution, if it exists.
161    pub fn parsed_url(&self) -> Option<&ParsedUrl> {
162        match self {
163            Self::Registry(_) => None,
164            Self::Url(dist) => Some(&dist.url.parsed_url),
165        }
166    }
167
168    /// Returns the [`WheelFilename`] of the distribution.
169    pub fn filename(&self) -> &WheelFilename {
170        match self {
171            Self::Registry(dist) => &dist.filename,
172            Self::Url(dist) => &dist.filename,
173        }
174    }
175}
176
177impl Hashed for CachedRegistryDist {
178    fn hashes(&self) -> &[HashDigest] {
179        self.hashes.as_slice()
180    }
181}
182
183impl Name for CachedRegistryDist {
184    fn name(&self) -> &PackageName {
185        &self.filename.name
186    }
187}
188
189impl Name for CachedDirectUrlDist {
190    fn name(&self) -> &PackageName {
191        &self.filename.name
192    }
193}
194
195impl Name for CachedDist {
196    fn name(&self) -> &PackageName {
197        match self {
198            Self::Registry(dist) => dist.name(),
199            Self::Url(dist) => dist.name(),
200        }
201    }
202}
203
204impl DistributionMetadata for CachedRegistryDist {
205    fn version_or_url(&self) -> VersionOrUrlRef<'_> {
206        VersionOrUrlRef::Version(&self.filename.version)
207    }
208}
209
210impl DistributionMetadata for CachedDirectUrlDist {
211    fn version_or_url(&self) -> VersionOrUrlRef<'_> {
212        VersionOrUrlRef::Url(&self.url.verbatim)
213    }
214}
215
216impl DistributionMetadata for CachedDist {
217    fn version_or_url(&self) -> VersionOrUrlRef<'_> {
218        match self {
219            Self::Registry(dist) => dist.version_or_url(),
220            Self::Url(dist) => dist.version_or_url(),
221        }
222    }
223}
224
225impl InstalledMetadata for CachedRegistryDist {
226    fn installed_version(&self) -> InstalledVersion<'_> {
227        InstalledVersion::Version(&self.filename.version)
228    }
229}
230
231impl InstalledMetadata for CachedDirectUrlDist {
232    fn installed_version(&self) -> InstalledVersion<'_> {
233        InstalledVersion::Url(&self.url.verbatim, &self.filename.version)
234    }
235}
236
237impl InstalledMetadata for CachedDist {
238    fn installed_version(&self) -> InstalledVersion<'_> {
239        match self {
240            Self::Registry(dist) => dist.installed_version(),
241            Self::Url(dist) => dist.installed_version(),
242        }
243    }
244}