use std::cell::RefCell;
use pubgrub::{
Dependencies, DependencyProvider, OfflineDependencyProvider, PackageResolutionStatistics,
Ranges, resolve,
};
type NumVS = Ranges<u32>;
struct CachingDependencyProvider<DP: DependencyProvider> {
remote_dependencies: DP,
cached_dependencies: RefCell<OfflineDependencyProvider<DP::P, DP::VS>>,
}
impl<DP: DependencyProvider> CachingDependencyProvider<DP> {
pub fn new(remote_dependencies_provider: DP) -> Self {
CachingDependencyProvider {
remote_dependencies: remote_dependencies_provider,
cached_dependencies: RefCell::new(OfflineDependencyProvider::new()),
}
}
}
impl<DP: DependencyProvider<M = String>> DependencyProvider for CachingDependencyProvider<DP> {
fn get_dependencies(
&self,
package: &DP::P,
version: &DP::V,
) -> Result<Dependencies<DP::P, DP::VS, DP::M>, DP::Err> {
let mut cache = self.cached_dependencies.borrow_mut();
match cache.get_dependencies(package, version) {
Ok(Dependencies::Unavailable(_)) => {
let dependencies = self.remote_dependencies.get_dependencies(package, version);
match dependencies {
Ok(Dependencies::Available(dependencies)) => {
cache.add_dependencies(
package.clone(),
version.clone(),
dependencies.clone(),
);
Ok(Dependencies::Available(dependencies))
}
Ok(Dependencies::Unavailable(reason)) => Ok(Dependencies::Unavailable(reason)),
error @ Err(_) => error,
}
}
Ok(dependencies) => Ok(dependencies),
Err(_) => unreachable!(),
}
}
fn choose_version(&self, package: &DP::P, ranges: &DP::VS) -> Result<Option<DP::V>, DP::Err> {
self.remote_dependencies.choose_version(package, ranges)
}
type Priority = DP::Priority;
fn prioritize(
&self,
package: &Self::P,
range: &Self::VS,
package_statistics: &PackageResolutionStatistics,
) -> Self::Priority {
self.remote_dependencies
.prioritize(package, range, package_statistics)
}
type Err = DP::Err;
type P = DP::P;
type V = DP::V;
type VS = DP::VS;
type M = DP::M;
}
fn main() {
let mut remote_dependencies_provider = OfflineDependencyProvider::<&str, NumVS>::new();
remote_dependencies_provider.add_dependencies("root", 1u32, Vec::new());
let caching_dependencies_provider =
CachingDependencyProvider::new(remote_dependencies_provider);
let solution = resolve(&caching_dependencies_provider, "root", 1u32);
println!("Solution: {solution:?}");
}