diff --git a/Cargo.lock b/Cargo.lock index 6bfa1da48..de3e7ab58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -968,17 +968,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "diff" version = "0.1.13" @@ -5048,7 +5037,6 @@ dependencies = [ "cache-key", "clap", "dashmap", - "derivative", "distribution-filename", "distribution-types", "either", diff --git a/Cargo.toml b/Cargo.toml index d22e30e2b..c11293554 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,6 @@ csv = { version = "1.3.0" } ctrlc = { version = "3.4.4" } dashmap = { version = "6.0.0" } data-encoding = { version = "2.5.0" } -derivative = { version = "2.2.0" } directories = { version = "5.0.1" } dirs-sys = { version = "0.4.1" } dunce = { version = "1.0.4" } diff --git a/crates/uv-resolver/Cargo.toml b/crates/uv-resolver/Cargo.toml index d9be46e66..df45d7a0f 100644 --- a/crates/uv-resolver/Cargo.toml +++ b/crates/uv-resolver/Cargo.toml @@ -38,7 +38,6 @@ uv-workspace = { workspace = true } anyhow = { workspace = true } clap = { workspace = true, features = ["derive"], optional = true } dashmap = { workspace = true } -derivative = { workspace = true } either = { workspace = true } futures = { workspace = true } indexmap = { workspace = true } diff --git a/crates/uv-resolver/src/pubgrub/report.rs b/crates/uv-resolver/src/pubgrub/report.rs index c992823e6..7e96ed0e8 100644 --- a/crates/uv-resolver/src/pubgrub/report.rs +++ b/crates/uv-resolver/src/pubgrub/report.rs @@ -3,7 +3,6 @@ use std::cmp::Ordering; use std::collections::{BTreeMap, BTreeSet}; use std::ops::Bound; -use derivative::Derivative; use indexmap::IndexSet; use owo_colors::OwoColorize; use pubgrub::{DerivationTree, Derived, External, Map, Range, ReportFormatter, Term}; @@ -719,22 +718,21 @@ impl PubGrubReportFormatter<'_> { } } -#[derive(Derivative, Debug, Clone)] -#[derivative(Hash, PartialEq, Eq)] +#[derive(Debug, Clone)] pub(crate) enum PubGrubHint { /// There are pre-release versions available for a package, but pre-releases weren't enabled /// for that package. /// PrereleaseAvailable { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` version: Version, }, /// A requirement included a pre-release marker, but pre-releases weren't enabled for that /// package. PrereleaseRequested { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` range: Range, }, /// Requirements were unavailable due to lookups in the index being disabled and no extra @@ -747,59 +745,161 @@ pub(crate) enum PubGrubHint { /// Metadata for a package could not be parsed. InvalidPackageMetadata { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` reason: String, }, /// The structure of a package was invalid (e.g., multiple `.dist-info` directories). InvalidPackageStructure { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` reason: String, }, /// Metadata for a package version could not be found. MissingVersionMetadata { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` version: Version, }, /// Metadata for a package version could not be parsed. InvalidVersionMetadata { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` version: Version, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` reason: String, }, /// Metadata for a package version was inconsistent (e.g., the package name did not match that /// of the file). InconsistentVersionMetadata { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` version: Version, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` reason: String, }, /// The structure of a package version was invalid (e.g., multiple `.dist-info` directories). InvalidVersionStructure { package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` version: Version, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` reason: String, }, /// The `Requires-Python` requirement was not satisfied. RequiresPython { source: PythonRequirementSource, requires_python: RequiresPython, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` package: PubGrubPackage, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` package_set: Range, - #[derivative(PartialEq = "ignore", Hash = "ignore")] + // excluded from `PartialEq` and `Hash` package_requires_python: Range, }, } +/// This private enum mirrors [`PubGrubHint`] but only includes fields that should be +/// used for `Eq` and `Hash` implementations. It is used to derive `PartialEq` and +/// `Hash` implementations for [`PubGrubHint`]. +#[derive(PartialEq, Eq, Hash)] +enum PubGrubHintCore { + PrereleaseAvailable { + package: PubGrubPackage, + }, + PrereleaseRequested { + package: PubGrubPackage, + }, + NoIndex, + Offline, + MissingPackageMetadata { + package: PubGrubPackage, + }, + InvalidPackageMetadata { + package: PubGrubPackage, + }, + InvalidPackageStructure { + package: PubGrubPackage, + }, + MissingVersionMetadata { + package: PubGrubPackage, + }, + InvalidVersionMetadata { + package: PubGrubPackage, + }, + InconsistentVersionMetadata { + package: PubGrubPackage, + }, + InvalidVersionStructure { + package: PubGrubPackage, + }, + RequiresPython { + source: PythonRequirementSource, + requires_python: RequiresPython, + }, +} + +impl From for PubGrubHintCore { + #[inline] + fn from(hint: PubGrubHint) -> Self { + match hint { + PubGrubHint::PrereleaseAvailable { package, .. } => { + Self::PrereleaseAvailable { package } + } + PubGrubHint::PrereleaseRequested { package, .. } => { + Self::PrereleaseRequested { package } + } + PubGrubHint::NoIndex => Self::NoIndex, + PubGrubHint::Offline => Self::Offline, + PubGrubHint::MissingPackageMetadata { package, .. } => { + Self::MissingPackageMetadata { package } + } + PubGrubHint::InvalidPackageMetadata { package, .. } => { + Self::InvalidPackageMetadata { package } + } + PubGrubHint::InvalidPackageStructure { package, .. } => { + Self::InvalidPackageStructure { package } + } + PubGrubHint::MissingVersionMetadata { package, .. } => { + Self::MissingVersionMetadata { package } + } + PubGrubHint::InvalidVersionMetadata { package, .. } => { + Self::InvalidVersionMetadata { package } + } + PubGrubHint::InconsistentVersionMetadata { package, .. } => { + Self::InconsistentVersionMetadata { package } + } + PubGrubHint::InvalidVersionStructure { package, .. } => { + Self::InvalidVersionStructure { package } + } + PubGrubHint::RequiresPython { + source, + requires_python, + .. + } => Self::RequiresPython { + source, + requires_python, + }, + } + } +} + +impl std::hash::Hash for PubGrubHint { + fn hash(&self, state: &mut H) { + let core = PubGrubHintCore::from(self.clone()); + core.hash(state); + } +} + +impl PartialEq for PubGrubHint { + fn eq(&self, other: &Self) -> bool { + let core = PubGrubHintCore::from(self.clone()); + let other_core = PubGrubHintCore::from(other.clone()); + core == other_core + } +} + +impl Eq for PubGrubHint {} + impl std::fmt::Display for PubGrubHint { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self {