Use distinct Constraints and Overrides types more widely (#2741)

## Summary

No functional changes.
This commit is contained in:
Charlie Marsh 2024-03-31 13:46:37 -04:00 committed by GitHub
parent 472d302ef0
commit 6d5b5ae9a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 71 additions and 45 deletions

View file

@ -21,6 +21,7 @@ uv-interpreter = { workspace = true }
uv-normalize = { workspace = true }
anyhow = { workspace = true }
itertools = { workspace = true }
rustc-hash = { workspace = true }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }

View file

@ -0,0 +1,35 @@
use std::hash::BuildHasherDefault;
use rustc_hash::FxHashMap;
use pep508_rs::Requirement;
use uv_normalize::PackageName;
/// A set of constraints for a set of requirements.
#[derive(Debug, Default, Clone)]
pub struct Constraints(FxHashMap<PackageName, Vec<Requirement>>);
impl Constraints {
/// Create a new set of constraints from a set of requirements.
pub fn from_requirements(requirements: Vec<Requirement>) -> Self {
let mut constraints: FxHashMap<PackageName, Vec<Requirement>> =
FxHashMap::with_capacity_and_hasher(requirements.len(), BuildHasherDefault::default());
for requirement in requirements {
constraints
.entry(requirement.name.clone())
.or_default()
.push(requirement);
}
Self(constraints)
}
/// Return an iterator over all [`Requirement`]s in the constraint set.
pub fn requirements(&self) -> impl Iterator<Item = &Requirement> {
self.0.values().flat_map(|requirements| requirements.iter())
}
/// Get the constraints for a package.
pub fn get(&self, name: &PackageName) -> Option<&Vec<Requirement>> {
self.0.get(name)
}
}

View file

@ -1,16 +1,20 @@
//! Fundamental types shared across `uv` crates.
pub use build_options::*;
pub use config_settings::*;
pub use constraints::*;
pub use downloads::*;
pub use name_specifiers::*;
pub use overrides::*;
pub use package_options::*;
pub use requirements::*;
pub use traits::*;
mod build_options;
mod config_settings;
mod constraints;
mod downloads;
mod name_specifiers;
mod overrides;
mod package_options;
mod requirements;
mod traits;

View file

@ -0,0 +1,50 @@
use std::hash::BuildHasherDefault;
use itertools::Either;
use rustc_hash::FxHashMap;
use pep508_rs::Requirement;
use uv_normalize::PackageName;
/// A set of overrides for a set of requirements.
#[derive(Debug, Default, Clone)]
pub struct Overrides(FxHashMap<PackageName, Vec<Requirement>>);
impl Overrides {
/// Create a new set of overrides from a set of requirements.
pub fn from_requirements(requirements: Vec<Requirement>) -> Self {
let mut overrides: FxHashMap<PackageName, Vec<Requirement>> =
FxHashMap::with_capacity_and_hasher(requirements.len(), BuildHasherDefault::default());
for requirement in requirements {
overrides
.entry(requirement.name.clone())
.or_default()
.push(requirement);
}
Self(overrides)
}
/// Return an iterator over all [`Requirement`]s in the override set.
pub fn requirements(&self) -> impl Iterator<Item = &Requirement> {
self.0.values().flat_map(|requirements| requirements.iter())
}
/// Get the overrides for a package.
pub fn get(&self, name: &PackageName) -> Option<&Vec<Requirement>> {
self.0.get(name)
}
/// Apply the overrides to a set of requirements.
pub fn apply<'a>(
&'a self,
requirements: &'a [Requirement],
) -> impl Iterator<Item = &Requirement> {
requirements.iter().flat_map(|requirement| {
if let Some(overrides) = self.get(&requirement.name) {
Either::Left(overrides.iter())
} else {
Either::Right(std::iter::once(requirement))
}
})
}
}