1use std::collections::{HashMap, HashSet};
2
3use indexmap::IndexMap;
4use semver::Version;
5
6use super::filter::push_filter_constraint;
7use super::{
8 PackageResolutionState, PackageVersions, PendingItem, RegisteredPackage, ResolvedGraph,
9 ResolvedNode, RootedSourceRef, VersionConstraint, VisitedSet,
10};
11use crate::config::FilterMode;
12use crate::source::ResolvedRef;
13use crate::types::{SourceId, SourceName};
14
15pub struct ResolverContext {
17 registry: IndexMap<SourceName, RegisteredPackage>,
18 package_states: HashMap<SourceName, PackageResolutionState>,
19 id_index: HashMap<SourceId, SourceName>,
20 version_constraints: HashMap<SourceName, Vec<(String, VersionConstraint)>>,
21 materialization_filters: HashMap<SourceName, Vec<FilterMode>>,
22 stack: Vec<PendingItem>,
23 visited: VisitedSet,
24 package_versions: PackageVersions,
25 direct_source_names: HashSet<SourceName>,
29 version_overrides: HashMap<SourceName, (ResolvedRef, RootedSourceRef, Option<Version>)>,
38 pending_restart: Option<(SourceName, ResolvedRef, RootedSourceRef, Option<Version>)>,
41}
42
43impl Default for ResolverContext {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49impl ResolverContext {
50 pub fn new() -> Self {
51 Self {
52 registry: IndexMap::new(),
53 package_states: HashMap::new(),
54 id_index: HashMap::new(),
55 version_constraints: HashMap::new(),
56 materialization_filters: HashMap::new(),
57 stack: Vec::new(),
58 visited: VisitedSet::new(),
59 package_versions: PackageVersions::new(),
60 direct_source_names: HashSet::new(),
61 version_overrides: HashMap::new(),
62 pending_restart: None,
63 }
64 }
65
66 pub(super) fn set_direct_sources(&mut self, names: HashSet<SourceName>) {
69 self.direct_source_names = names;
70 }
71
72 pub(super) fn is_direct_source(&self, name: &SourceName) -> bool {
75 self.direct_source_names.contains(name)
76 }
77
78 pub(super) fn set_version_overrides(
82 &mut self,
83 overrides: HashMap<SourceName, (ResolvedRef, RootedSourceRef, Option<Version>)>,
84 ) {
85 self.version_overrides = overrides;
86 }
87
88 pub(super) fn version_override(
91 &self,
92 name: &SourceName,
93 ) -> Option<&(ResolvedRef, RootedSourceRef, Option<Version>)> {
94 self.version_overrides.get(name)
95 }
96
97 pub(super) fn set_pending_restart(
101 &mut self,
102 package: SourceName,
103 new_ref: ResolvedRef,
104 new_rooted: RootedSourceRef,
105 latest_version: Option<Version>,
106 ) {
107 self.pending_restart = Some((package, new_ref, new_rooted, latest_version));
108 }
109
110 pub(super) fn take_pending_restart(
112 &mut self,
113 ) -> Option<(SourceName, ResolvedRef, RootedSourceRef, Option<Version>)> {
114 self.pending_restart.take()
115 }
116
117 pub(super) fn registry(&self) -> &IndexMap<SourceName, RegisteredPackage> {
118 &self.registry
119 }
120
121 pub(super) fn registry_mut(&mut self) -> &mut IndexMap<SourceName, RegisteredPackage> {
122 &mut self.registry
123 }
124
125 pub(super) fn package_states(&self) -> &HashMap<SourceName, PackageResolutionState> {
126 &self.package_states
127 }
128
129 pub(super) fn package_states_mut(
130 &mut self,
131 ) -> &mut HashMap<SourceName, PackageResolutionState> {
132 &mut self.package_states
133 }
134
135 pub(super) fn id_index(&self) -> &HashMap<SourceId, SourceName> {
136 &self.id_index
137 }
138
139 pub(super) fn id_index_mut(&mut self) -> &mut HashMap<SourceId, SourceName> {
140 &mut self.id_index
141 }
142
143 pub(super) fn version_constraints(
144 &self,
145 ) -> &HashMap<SourceName, Vec<(String, VersionConstraint)>> {
146 &self.version_constraints
147 }
148
149 pub(super) fn materialization_filters(&self) -> &HashMap<SourceName, Vec<FilterMode>> {
150 &self.materialization_filters
151 }
152
153 pub(super) fn visited(&self) -> &VisitedSet {
154 &self.visited
155 }
156
157 pub(super) fn visited_mut(&mut self) -> &mut VisitedSet {
158 &mut self.visited
159 }
160
161 pub(super) fn package_versions_mut(&mut self) -> &mut PackageVersions {
162 &mut self.package_versions
163 }
164
165 pub fn add_version_constraint(
166 &mut self,
167 package: &SourceName,
168 requester: &str,
169 constraint: VersionConstraint,
170 ) {
171 self.version_constraints
172 .entry(package.clone())
173 .or_default()
174 .push((requester.to_string(), constraint));
175 }
176
177 pub fn add_filter(&mut self, package: &SourceName, filter: FilterMode) {
178 push_filter_constraint(&mut self.materialization_filters, package, &filter);
179 }
180
181 pub fn push_pending(&mut self, item: PendingItem) {
182 self.stack.push(item);
183 }
184
185 pub fn pop_pending(&mut self) -> Option<PendingItem> {
186 self.stack.pop()
187 }
188
189 pub fn into_graph(self) -> ResolvedGraph {
190 let mut nodes: IndexMap<SourceName, ResolvedNode> = IndexMap::new();
191 for (name, package) in self.registry {
192 nodes.insert(name, package.node);
193 }
194
195 let mut order: Vec<SourceName> = nodes.keys().cloned().collect();
196 order.sort();
197
198 ResolvedGraph {
199 nodes,
200 order,
201 filters: self.materialization_filters,
202 }
203 }
204}