use std::path::Path;
use std::sync::Arc;
use papaya::{HashMap, ResizeMode};
use uv_configuration::{BuildKind, NoSources};
use uv_normalize::PackageName;
use uv_python::PythonEnvironment;
#[derive(Debug, Default, Copy, Clone)]
pub enum BuildIsolation<'a> {
#[default]
Isolated,
Shared(&'a PythonEnvironment),
SharedPackage(&'a PythonEnvironment, &'a [PackageName]),
}
impl BuildIsolation<'_> {
pub fn is_isolated(&self, package: Option<&PackageName>) -> bool {
match self {
Self::Isolated => true,
Self::Shared(_) => false,
Self::SharedPackage(_, packages) => {
package.is_none_or(|package| !packages.iter().any(|p| p == package))
}
}
}
pub fn shared_environment(&self, package: Option<&PackageName>) -> Option<&PythonEnvironment> {
match self {
Self::Isolated => None,
Self::Shared(env) => Some(env),
Self::SharedPackage(env, packages) => {
if package.is_some_and(|package| packages.iter().any(|p| p == package)) {
Some(env)
} else {
None
}
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct BuildKey {
pub base_python: Box<Path>,
pub source_root: Box<Path>,
pub subdirectory: Option<Box<Path>>,
pub no_sources: NoSources,
pub build_kind: BuildKind,
}
#[derive(Debug)]
pub struct BuildArena<T>(Arc<HashMap<BuildKey, Arc<T>>>);
impl<T> Default for BuildArena<T> {
fn default() -> Self {
Self(Arc::new(
HashMap::builder().resize_mode(ResizeMode::Blocking).build(),
))
}
}
impl<T> Clone for BuildArena<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> BuildArena<T> {
pub fn insert(&self, key: BuildKey, value: impl Into<Arc<T>>) {
self.0.pin().insert(key, value.into());
}
pub fn remove(&self, key: &BuildKey) -> Option<Arc<T>> {
self.0.pin().remove(key).cloned()
}
}