11// SPDX-License-Identifier: MPL-2.0
22
33use std:: cell:: RefCell ;
4- use std:: collections:: BTreeMap ;
54use std:: fmt:: { Debug , Display } ;
65use std:: hash:: Hash ;
76
87use pubgrub:: {
98 resolve, Dependencies , DependencyConstraints , DependencyProvider , Map ,
10- OfflineDependencyProvider , Package , PackageArena , Ranges ,
9+ OfflineDependencyProvider , Package , PackageArena , PubGrubError , Ranges , SelectedDependencies ,
10+ Version , VersionRanges , VersionSet ,
1111} ;
1212
1313type NumVS = Ranges < u32 > ;
14- type CachedDeps < V , VS > = RefCell < Map < Package , BTreeMap < V , DependencyConstraints < VS > > > > ;
14+
15+ trait RemoteProvider : DependencyProvider {
16+ type R : VersionRanges ;
17+
18+ fn get_package_version (
19+ & self ,
20+ p : & Self :: P ,
21+ v : & <Self :: R as VersionRanges >:: V ,
22+ ) -> Option < Version > ;
23+ }
24+
25+ impl < P : Debug + Display + Clone + Eq + Hash , R : VersionRanges > RemoteProvider
26+ for OfflineDependencyProvider < P , R >
27+ {
28+ type R = R ;
29+
30+ fn get_package_version (
31+ & self ,
32+ p : & Self :: P ,
33+ v : & <Self :: R as VersionRanges >:: V ,
34+ ) -> Option < Version > {
35+ self . get_package_version ( p, v)
36+ }
37+ }
1538
1639// An example implementing caching dependency provider that will
1740// store queried dependencies in memory and check them before querying more from remote.
18- struct CachingDependencyProvider < DP : DependencyProvider >
41+ struct CachingDependencyProvider < DP : RemoteProvider < R = R > , R : VersionRanges >
1942where
2043 DP :: P : Debug + Display + Clone + Eq + Hash ,
2144{
2245 remote_dependencies : DP ,
23- cached_dependencies : CachedDeps < DP :: V , DP :: VS > ,
46+ cached_dependencies : RefCell < Map < Package , Map < Version , DependencyConstraints > > > ,
2447}
2548
26- impl < DP : DependencyProvider > CachingDependencyProvider < DP >
49+ impl < DP : RemoteProvider < R = R > , R : VersionRanges > CachingDependencyProvider < DP , R >
2750where
2851 DP :: P : Debug + Display + Clone + Eq + Hash ,
2952{
30- pub fn new ( remote_dependencies_provider : DP ) -> Self {
53+ fn new ( remote_dependencies_provider : DP ) -> Self {
3154 CachingDependencyProvider {
3255 remote_dependencies : remote_dependencies_provider,
3356 cached_dependencies : Default :: default ( ) ,
3457 }
3558 }
59+
60+ fn resolve (
61+ & mut self ,
62+ p : <Self as DependencyProvider >:: P ,
63+ v : impl Into < R :: V > ,
64+ ) -> Result < SelectedDependencies < Self > , PubGrubError < Self > > {
65+ let Some ( version) = self . remote_dependencies . get_package_version ( & p, & v. into ( ) ) else {
66+ return Err ( PubGrubError :: NoRoot ) ;
67+ } ;
68+ resolve ( self , p, version)
69+ }
3670}
3771
38- impl < DP : DependencyProvider < M = & ' static str > > DependencyProvider for CachingDependencyProvider < DP >
72+ impl < DP : RemoteProvider < R = R > , R : VersionRanges > DependencyProvider
73+ for CachingDependencyProvider < DP , R >
3974where
4075 DP :: P : Debug + Display + Clone + Eq + Hash ,
76+ R :: V : Clone ,
4177{
4278 // Cache dependencies if they were already queried
4379 fn get_dependencies (
4480 & mut self ,
4581 package : Package ,
46- version : & DP :: V ,
82+ version : Version ,
4783 package_store : & mut PackageArena < Self :: P > ,
48- ) -> Result < Dependencies < DP :: VS , DP :: M > , DP :: Err > {
84+ ) -> Result < Dependencies < DP :: M > , DP :: Err > {
4985 let mut cache = self . cached_dependencies . borrow_mut ( ) ;
50- if let Some ( deps) = cache. get ( & package) . and_then ( |vmap| vmap. get ( version) ) {
86+ if let Some ( deps) = cache. get ( & package) . and_then ( |vmap| vmap. get ( & version) ) {
5187 return Ok ( Dependencies :: Available ( deps. clone ( ) ) ) ;
5288 }
5389
5995 cache
6096 . entry ( package)
6197 . or_default ( )
62- . insert ( version. clone ( ) , deps. clone ( ) ) ;
98+ . insert ( version, deps. clone ( ) ) ;
6399 Ok ( Dependencies :: Available ( deps) )
64100 }
65101
@@ -71,31 +107,42 @@ where
71107 fn choose_version (
72108 & mut self ,
73109 package : Package ,
74- ranges : & DP :: VS ,
110+ range : VersionSet ,
75111 package_store : & PackageArena < Self :: P > ,
76- ) -> Result < Option < DP :: V > , DP :: Err > {
112+ ) -> Result < Option < Version > , DP :: Err > {
77113 self . remote_dependencies
78- . choose_version ( package, ranges , package_store)
114+ . choose_version ( package, range , package_store)
79115 }
80116
81117 type Priority = DP :: Priority ;
82118
83119 fn prioritize (
84120 & mut self ,
85121 package : Package ,
86- ranges : & DP :: VS ,
122+ range : VersionSet ,
87123 package_store : & PackageArena < Self :: P > ,
88124 ) -> Self :: Priority {
89125 self . remote_dependencies
90- . prioritize ( package, ranges , package_store)
126+ . prioritize ( package, range , package_store)
91127 }
92128
93129 type Err = DP :: Err ;
94130
95131 type P = DP :: P ;
96- type V = DP :: V ;
97- type VS = DP :: VS ;
98132 type M = DP :: M ;
133+
134+ fn package_version_repr < ' a > ( & ' a self , pkg : & ' a Self :: P , version : Version ) -> impl Display + ' a {
135+ self . remote_dependencies . package_version_repr ( pkg, version)
136+ }
137+
138+ fn package_version_set_repr < ' a > (
139+ & ' a self ,
140+ pkg : & ' a Self :: P ,
141+ version_set : VersionSet ,
142+ ) -> impl Display + ' a {
143+ self . remote_dependencies
144+ . package_version_set_repr ( pkg, version_set)
145+ }
99146}
100147
101148fn main ( ) {
@@ -108,6 +155,6 @@ fn main() {
108155 let mut caching_dependencies_provider =
109156 CachingDependencyProvider :: new ( remote_dependencies_provider) ;
110157
111- let solution = resolve ( & mut caching_dependencies_provider , "root" , 1u32 ) ;
158+ let solution = caching_dependencies_provider . resolve ( "root" , 1u32 ) ;
112159 println ! ( "Solution: {:?}" , solution) ;
113160}
0 commit comments