Skip to content

Commit 423bf05

Browse files
committed
Make IndexSummary an enum
1 parent 385dfb6 commit 423bf05

File tree

2 files changed

+85
-47
lines changed

2 files changed

+85
-47
lines changed

src/cargo/sources/registry/index.rs

Lines changed: 83 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,34 @@ enum MaybeIndexSummary {
189189
/// from a line from a raw index file, or a JSON blob from on-disk index cache.
190190
///
191191
/// In addition to a full [`Summary`], we have information on whether it is `yanked`.
192-
pub struct IndexSummary {
193-
pub summary: Summary,
194-
pub yanked: bool,
195-
/// Schema version, see [`IndexPackage::v`].
196-
v: u32,
192+
#[derive(Clone, Debug)]
193+
pub enum IndexSummary {
194+
/// Available for consideration
195+
Candidate(Summary),
196+
/// Yanked within its registry
197+
Yanked(Summary),
198+
/// From a newer schema version and is likely incomplete or inaccurate
199+
Unsupported(Summary, u32),
200+
}
201+
202+
impl IndexSummary {
203+
/// Extract the summary from any variant
204+
pub fn as_summary(&self) -> &Summary {
205+
match self {
206+
IndexSummary::Candidate(sum)
207+
| IndexSummary::Yanked(sum)
208+
| IndexSummary::Unsupported(sum, _) => sum,
209+
}
210+
}
211+
212+
/// Extract the package id from any variant
213+
pub fn package_id(&self) -> PackageId {
214+
match self {
215+
IndexSummary::Candidate(sum)
216+
| IndexSummary::Yanked(sum)
217+
| IndexSummary::Unsupported(sum, _) => sum.package_id(),
218+
}
219+
}
197220
}
198221

199222
/// A representation of the cache on disk that Cargo maintains of summaries.
@@ -387,11 +410,11 @@ impl<'cfg> RegistryIndex<'cfg> {
387410
let req = OptVersionReq::exact(pkg.version());
388411
let summary = self.summaries(&pkg.name(), &req, load)?;
389412
let summary = ready!(summary)
390-
.filter(|s| s.summary.version() == pkg.version())
413+
.filter(|s| s.package_id().version() == pkg.version())
391414
.next();
392415
Poll::Ready(Ok(summary
393416
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?
394-
.summary
417+
.as_summary()
395418
.checksum()
396419
.ok_or_else(|| internal(format!("no hash listed for {}", pkg)))?))
397420
}
@@ -435,26 +458,24 @@ impl<'cfg> RegistryIndex<'cfg> {
435458
.versions
436459
.iter_mut()
437460
.filter_map(move |(k, v)| if req.matches(k) { Some(v) } else { None })
438-
.filter_map(move |maybe| match maybe.parse(raw_data, source_id) {
439-
Ok(summary) => Some(summary),
440-
Err(e) => {
441-
info!("failed to parse `{}` registry package: {}", name, e);
442-
None
443-
}
444-
})
445-
.filter(move |is| {
446-
if is.v == 3 && bindeps {
447-
true
448-
} else if is.v > INDEX_V_MAX {
449-
debug!(
450-
"unsupported schema version {} ({} {})",
451-
is.v,
452-
is.summary.name(),
453-
is.summary.version()
454-
);
455-
false
456-
} else {
457-
true
461+
.filter_map(move |maybe| {
462+
match maybe.parse(raw_data, source_id, bindeps) {
463+
Ok(sum @ IndexSummary::Candidate(_) | sum @ IndexSummary::Yanked(_)) => {
464+
Some(sum)
465+
}
466+
Ok(IndexSummary::Unsupported(summary, v)) => {
467+
debug!(
468+
"unsupported schema version {} ({} {})",
469+
v,
470+
summary.name(),
471+
summary.version()
472+
);
473+
None
474+
}
475+
Err(e) => {
476+
info!("failed to parse `{}` registry package: {}", name, e);
477+
None
478+
}
458479
}
459480
})))
460481
}
@@ -573,12 +594,14 @@ impl<'cfg> RegistryIndex<'cfg> {
573594
// does not satisfy the requirements, then resolution will
574595
// fail. Unfortunately, whether or not something is optional
575596
// is not known here.
576-
.filter(|s| (online || load.is_crate_downloaded(s.summary.package_id())))
597+
.filter(|s| (online || load.is_crate_downloaded(s.package_id())))
577598
// Next filter out all yanked packages. Some yanked packages may
578599
// leak through if they're in a whitelist (aka if they were
579600
// previously in `Cargo.lock`
580-
.filter(|s| !s.yanked || yanked_whitelist.contains(&s.summary.package_id()))
581-
.map(|s| s.summary.clone());
601+
.filter(|s| {
602+
!matches!(s, IndexSummary::Yanked(_)) || yanked_whitelist.contains(&s.package_id())
603+
})
604+
.map(|s| s.clone());
582605

583606
// Handle `cargo update --precise` here.
584607
let precise = source_id.precise_registry_version(name);
@@ -589,7 +612,7 @@ impl<'cfg> RegistryIndex<'cfg> {
589612
// by build metadata. This shouldn't be allowed, but since
590613
// it is, this will honor it if requested. However, if not
591614
// specified, then ignore it.
592-
let s_vers = s.version();
615+
let s_vers = s.package_id().version();
593616
match (s_vers.build.is_empty(), requested.build.is_empty()) {
594617
(true, true) => s_vers == requested,
595618
(true, false) => false,
@@ -611,7 +634,7 @@ impl<'cfg> RegistryIndex<'cfg> {
611634

612635
let mut count = 0;
613636
for summary in summaries {
614-
f(summary);
637+
f(summary.as_summary().clone());
615638
count += 1;
616639
}
617640
Poll::Ready(Ok(count))
@@ -625,8 +648,8 @@ impl<'cfg> RegistryIndex<'cfg> {
625648
) -> Poll<CargoResult<bool>> {
626649
let req = OptVersionReq::exact(pkg.version());
627650
let found = ready!(self.summaries(&pkg.name(), &req, load))?
628-
.filter(|s| s.summary.version() == pkg.version())
629-
.any(|summary| summary.yanked);
651+
.filter(|s| s.package_id().version() == pkg.version())
652+
.any(|summary| matches!(summary, IndexSummary::Yanked(_)));
630653
Poll::Ready(Ok(found))
631654
}
632655
}
@@ -682,6 +705,8 @@ impl Summaries {
682705

683706
let response = ready!(load.load(root, relative, index_version.as_deref())?);
684707

708+
let bindeps = config.cli_unstable().bindeps;
709+
685710
match response {
686711
LoadResponse::CacheValid => {
687712
tracing::debug!("fast path for registry cache of {:?}", relative);
@@ -712,7 +737,7 @@ impl Summaries {
712737
// allow future cargo implementations to break the
713738
// interpretation of each line here and older cargo will simply
714739
// ignore the new lines.
715-
let summary = match IndexSummary::parse(line, source_id) {
740+
let summary = match IndexSummary::parse(line, source_id, bindeps) {
716741
Ok(summary) => summary,
717742
Err(e) => {
718743
// This should only happen when there is an index
@@ -731,7 +756,7 @@ impl Summaries {
731756
continue;
732757
}
733758
};
734-
let version = summary.summary.package_id().version().clone();
759+
let version = summary.package_id().version().clone();
735760
cache.versions.push((version.clone(), line));
736761
ret.versions.insert(version, summary.into());
737762
}
@@ -865,12 +890,17 @@ impl MaybeIndexSummary {
865890
/// Does nothing if this is already `Parsed`, and otherwise the `raw_data`
866891
/// passed in is sliced with the bounds in `Unparsed` and then actually
867892
/// parsed.
868-
fn parse(&mut self, raw_data: &[u8], source_id: SourceId) -> CargoResult<&IndexSummary> {
893+
fn parse(
894+
&mut self,
895+
raw_data: &[u8],
896+
source_id: SourceId,
897+
bindeps: bool,
898+
) -> CargoResult<&IndexSummary> {
869899
let (start, end) = match self {
870900
MaybeIndexSummary::Unparsed { start, end } => (*start, *end),
871901
MaybeIndexSummary::Parsed(summary) => return Ok(summary),
872902
};
873-
let summary = IndexSummary::parse(&raw_data[start..end], source_id)?;
903+
let summary = IndexSummary::parse(&raw_data[start..end], source_id, bindeps)?;
874904
*self = MaybeIndexSummary::Parsed(summary);
875905
match self {
876906
MaybeIndexSummary::Unparsed { .. } => unreachable!(),
@@ -891,7 +921,7 @@ impl IndexSummary {
891921
///
892922
/// The `line` provided is expected to be valid JSON. It is supposed to be
893923
/// a [`IndexPackage`].
894-
fn parse(line: &[u8], source_id: SourceId) -> CargoResult<IndexSummary> {
924+
fn parse(line: &[u8], source_id: SourceId, bindeps: bool) -> CargoResult<IndexSummary> {
895925
// ****CAUTION**** Please be extremely careful with returning errors
896926
// from this function. Entries that error are not included in the
897927
// index cache, and can cause cargo to get confused when switching
@@ -924,11 +954,20 @@ impl IndexSummary {
924954
}
925955
let mut summary = Summary::new(pkgid, deps, &features, links, rust_version)?;
926956
summary.set_checksum(cksum);
927-
Ok(IndexSummary {
928-
summary,
929-
yanked: yanked.unwrap_or(false),
930-
v,
931-
})
957+
958+
let v_max = if bindeps {
959+
INDEX_V_MAX + 1
960+
} else {
961+
INDEX_V_MAX
962+
};
963+
964+
if v_max < v {
965+
return Ok(IndexSummary::Unsupported(summary, v));
966+
}
967+
if yanked.unwrap_or(false) {
968+
return Ok(IndexSummary::Yanked(summary));
969+
}
970+
Ok(IndexSummary::Candidate(summary))
932971
}
933972
}
934973

src/cargo/sources/registry/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -695,11 +695,10 @@ impl<'cfg> RegistrySource<'cfg> {
695695
.index
696696
.summaries(&package.name(), &req, &mut *self.ops)?
697697
.expect("a downloaded dep now pending!?")
698-
.map(|s| s.summary.clone())
699-
.filter(|s| s.version() == package.version())
698+
.filter(|s| s.package_id().version() == package.version())
700699
.next()
701700
.expect("summary not found");
702-
if let Some(cksum) = summary_with_cksum.checksum() {
701+
if let Some(cksum) = summary_with_cksum.as_summary().checksum() {
703702
pkg.manifest_mut()
704703
.summary_mut()
705704
.set_checksum(cksum.to_string());

0 commit comments

Comments
 (0)