1use std::collections::{BTreeMap, HashMap};
2
3use indexmap::IndexMap;
4
5use super::filter::push_filter_constraint;
6use super::{
7 PackageResolutionState, PackageVersions, PendingItem, RegisteredPackage, ResolvedGraph,
8 ResolvedNode, RootedSourceRef, VersionConstraint, VisitedSet,
9};
10use crate::config::FilterMode;
11use crate::source::ResolvedRef;
12use crate::types::{SourceId, SourceName};
13
14pub struct ResolverContext {
16 registry: IndexMap<SourceName, RegisteredPackage>,
17 package_states: HashMap<SourceName, PackageResolutionState>,
18 id_index: HashMap<SourceId, SourceName>,
19 version_constraints: HashMap<SourceName, Vec<(String, VersionConstraint)>>,
20 materialization_filters: HashMap<SourceName, Vec<FilterMode>>,
21 stack: Vec<PendingItem>,
22 visited: VisitedSet,
23 package_versions: PackageVersions,
24 version_overrides: HashMap<
33 SourceName,
34 (
35 ResolvedRef,
36 RootedSourceRef,
37 crate::staging::HookSurfaceState,
38 ),
39 >,
40 pending_restart: Option<(
43 SourceName,
44 ResolvedRef,
45 RootedSourceRef,
46 crate::staging::HookSurfaceState,
47 )>,
48 unreadable_hook_surfaces: BTreeMap<SourceName, std::collections::BTreeSet<String>>,
49}
50
51impl Default for ResolverContext {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl ResolverContext {
58 pub fn new() -> Self {
59 Self {
60 registry: IndexMap::new(),
61 package_states: HashMap::new(),
62 id_index: HashMap::new(),
63 version_constraints: HashMap::new(),
64 materialization_filters: HashMap::new(),
65 stack: Vec::new(),
66 visited: VisitedSet::new(),
67 package_versions: PackageVersions::new(),
68 version_overrides: HashMap::new(),
69 pending_restart: None,
70 unreadable_hook_surfaces: BTreeMap::new(),
71 }
72 }
73
74 pub(super) fn set_version_overrides(
78 &mut self,
79 overrides: HashMap<
80 SourceName,
81 (
82 ResolvedRef,
83 RootedSourceRef,
84 crate::staging::HookSurfaceState,
85 ),
86 >,
87 ) {
88 self.version_overrides = overrides;
89 }
90
91 pub(super) fn version_override(
94 &self,
95 name: &SourceName,
96 ) -> Option<(
97 ResolvedRef,
98 RootedSourceRef,
99 crate::staging::HookSurfaceState,
100 )> {
101 self.version_overrides.get(name).cloned()
102 }
103
104 pub(super) fn set_version_override(
105 &mut self,
106 name: SourceName,
107 value: (
108 ResolvedRef,
109 RootedSourceRef,
110 crate::staging::HookSurfaceState,
111 ),
112 ) {
113 self.version_overrides.insert(name, value);
114 }
115
116 pub(super) fn version_overrides(
117 &self,
118 ) -> &HashMap<
119 SourceName,
120 (
121 ResolvedRef,
122 RootedSourceRef,
123 crate::staging::HookSurfaceState,
124 ),
125 > {
126 &self.version_overrides
127 }
128
129 pub(super) fn set_pending_restart(
133 &mut self,
134 package: SourceName,
135 new_ref: ResolvedRef,
136 new_rooted: RootedSourceRef,
137 hook_surface: crate::staging::HookSurfaceState,
138 ) {
139 self.pending_restart = Some((package, new_ref, new_rooted, hook_surface));
140 }
141
142 pub(super) fn take_pending_restart(
144 &mut self,
145 ) -> Option<(
146 SourceName,
147 ResolvedRef,
148 RootedSourceRef,
149 crate::staging::HookSurfaceState,
150 )> {
151 self.pending_restart.take()
152 }
153
154 pub(super) fn set_hook_surface(
155 &mut self,
156 source_name: &SourceName,
157 state: crate::staging::HookSurfaceState,
158 ) {
159 if let crate::staging::HookSurfaceState::Unreadable { hook_names } = state {
160 self.unreadable_hook_surfaces
161 .insert(source_name.clone(), hook_names);
162 }
163 }
164
165 pub(super) fn registry(&self) -> &IndexMap<SourceName, RegisteredPackage> {
166 &self.registry
167 }
168
169 pub(super) fn registry_mut(&mut self) -> &mut IndexMap<SourceName, RegisteredPackage> {
170 &mut self.registry
171 }
172
173 pub(super) fn package_states(&self) -> &HashMap<SourceName, PackageResolutionState> {
174 &self.package_states
175 }
176
177 pub(super) fn package_states_mut(
178 &mut self,
179 ) -> &mut HashMap<SourceName, PackageResolutionState> {
180 &mut self.package_states
181 }
182
183 pub(super) fn id_index(&self) -> &HashMap<SourceId, SourceName> {
184 &self.id_index
185 }
186
187 pub(super) fn id_index_mut(&mut self) -> &mut HashMap<SourceId, SourceName> {
188 &mut self.id_index
189 }
190
191 pub(super) fn version_constraints(
192 &self,
193 ) -> &HashMap<SourceName, Vec<(String, VersionConstraint)>> {
194 &self.version_constraints
195 }
196
197 pub(super) fn materialization_filters(&self) -> &HashMap<SourceName, Vec<FilterMode>> {
198 &self.materialization_filters
199 }
200
201 pub(super) fn visited(&self) -> &VisitedSet {
202 &self.visited
203 }
204
205 pub(super) fn visited_mut(&mut self) -> &mut VisitedSet {
206 &mut self.visited
207 }
208
209 pub(super) fn package_versions_mut(&mut self) -> &mut PackageVersions {
210 &mut self.package_versions
211 }
212
213 pub fn add_version_constraint(
214 &mut self,
215 package: &SourceName,
216 requester: &str,
217 constraint: VersionConstraint,
218 ) {
219 self.version_constraints
220 .entry(package.clone())
221 .or_default()
222 .push((requester.to_string(), constraint));
223 }
224
225 pub fn add_filter(&mut self, package: &SourceName, filter: FilterMode) {
226 push_filter_constraint(&mut self.materialization_filters, package, &filter);
227 }
228
229 pub fn push_pending(&mut self, item: PendingItem) {
230 self.stack.push(item);
231 }
232
233 pub fn pop_pending(&mut self) -> Option<PendingItem> {
234 self.stack.pop()
235 }
236
237 pub fn into_graph(self) -> ResolvedGraph {
238 let mut nodes: IndexMap<SourceName, ResolvedNode> = IndexMap::new();
239 for (name, package) in self.registry {
240 nodes.insert(name, package.node);
241 }
242
243 let mut order: Vec<SourceName> = nodes.keys().cloned().collect();
244 order.sort();
245
246 ResolvedGraph {
247 nodes,
248 order,
249 filters: self.materialization_filters,
250 version_constraints: self.version_constraints,
251 unreadable_hook_surfaces: self.unreadable_hook_surfaces,
252 }
253 }
254}