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_pending_restart(
108 &mut self,
109 package: SourceName,
110 new_ref: ResolvedRef,
111 new_rooted: RootedSourceRef,
112 hook_surface: crate::staging::HookSurfaceState,
113 ) {
114 self.pending_restart = Some((package, new_ref, new_rooted, hook_surface));
115 }
116
117 pub(super) fn take_pending_restart(
119 &mut self,
120 ) -> Option<(
121 SourceName,
122 ResolvedRef,
123 RootedSourceRef,
124 crate::staging::HookSurfaceState,
125 )> {
126 self.pending_restart.take()
127 }
128
129 pub(super) fn set_hook_surface(
130 &mut self,
131 source_name: &SourceName,
132 state: crate::staging::HookSurfaceState,
133 ) {
134 if let crate::staging::HookSurfaceState::Unreadable { hook_names } = state {
135 self.unreadable_hook_surfaces
136 .insert(source_name.clone(), hook_names);
137 }
138 }
139
140 pub(super) fn registry(&self) -> &IndexMap<SourceName, RegisteredPackage> {
141 &self.registry
142 }
143
144 pub(super) fn registry_mut(&mut self) -> &mut IndexMap<SourceName, RegisteredPackage> {
145 &mut self.registry
146 }
147
148 pub(super) fn package_states(&self) -> &HashMap<SourceName, PackageResolutionState> {
149 &self.package_states
150 }
151
152 pub(super) fn package_states_mut(
153 &mut self,
154 ) -> &mut HashMap<SourceName, PackageResolutionState> {
155 &mut self.package_states
156 }
157
158 pub(super) fn id_index(&self) -> &HashMap<SourceId, SourceName> {
159 &self.id_index
160 }
161
162 pub(super) fn id_index_mut(&mut self) -> &mut HashMap<SourceId, SourceName> {
163 &mut self.id_index
164 }
165
166 pub(super) fn version_constraints(
167 &self,
168 ) -> &HashMap<SourceName, Vec<(String, VersionConstraint)>> {
169 &self.version_constraints
170 }
171
172 pub(super) fn materialization_filters(&self) -> &HashMap<SourceName, Vec<FilterMode>> {
173 &self.materialization_filters
174 }
175
176 pub(super) fn visited(&self) -> &VisitedSet {
177 &self.visited
178 }
179
180 pub(super) fn visited_mut(&mut self) -> &mut VisitedSet {
181 &mut self.visited
182 }
183
184 pub(super) fn package_versions_mut(&mut self) -> &mut PackageVersions {
185 &mut self.package_versions
186 }
187
188 pub fn add_version_constraint(
189 &mut self,
190 package: &SourceName,
191 requester: &str,
192 constraint: VersionConstraint,
193 ) {
194 self.version_constraints
195 .entry(package.clone())
196 .or_default()
197 .push((requester.to_string(), constraint));
198 }
199
200 pub fn add_filter(&mut self, package: &SourceName, filter: FilterMode) {
201 push_filter_constraint(&mut self.materialization_filters, package, &filter);
202 }
203
204 pub fn push_pending(&mut self, item: PendingItem) {
205 self.stack.push(item);
206 }
207
208 pub fn pop_pending(&mut self) -> Option<PendingItem> {
209 self.stack.pop()
210 }
211
212 pub fn into_graph(self) -> ResolvedGraph {
213 let mut nodes: IndexMap<SourceName, ResolvedNode> = IndexMap::new();
214 for (name, package) in self.registry {
215 nodes.insert(name, package.node);
216 }
217
218 let mut order: Vec<SourceName> = nodes.keys().cloned().collect();
219 order.sort();
220
221 ResolvedGraph {
222 nodes,
223 order,
224 filters: self.materialization_filters,
225 version_constraints: self.version_constraints,
226 unreadable_hook_surfaces: self.unreadable_hook_surfaces,
227 }
228 }
229}