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#[derive(Debug, Clone, Hash, PartialEq, Eq)]
15#[allow(clippy::large_enum_variant)]
16pub enum CachedDist {
17 Registry(CachedRegistryDist),
19 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 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 pub fn path(&self) -> &Path {
138 match self {
139 Self::Registry(dist) => &dist.path,
140 Self::Url(dist) => &dist.path,
141 }
142 }
143
144 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 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 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 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}