1212
1313use {
1414 crate :: {
15- context:: Context ,
16- instance:: Instance ,
17- instance_state:: InstanceState ,
18- package_json:: PackageJson ,
19- specifier:: { semver_range:: SemverRange , Specifier } ,
15+ context:: Context , instance:: Instance , instance_state:: InstanceState , package_json:: PackageJson , specifier:: Specifier ,
2016 version_group:: VersionGroupVariant ,
2117 } ,
2218 itertools:: Itertools ,
@@ -49,7 +45,7 @@ pub struct Dependency {
4945 /// The expected version specifier which all instances of this dependency
5046 /// should be set to, in the event that they should all use the same version.
5147 /// RefCell allows mutation during inspection without &mut Context.
52- pub expected : RefCell < Option < Specifier > > ,
48+ pub expected : RefCell < Option < Rc < Specifier > > > ,
5349 /// Whether the internal name for this dependency is an alias.
5450 pub has_alias : bool ,
5551 /// Every instance of this dependency in this version group.
@@ -63,7 +59,7 @@ pub struct Dependency {
6359 /// The name of the dependency, e.g., "react", "@types/node"
6460 pub internal_name : String ,
6561 /// The version to pin all instances to when variant is `Pinned`
66- pub pinned_specifier : Option < Specifier > ,
62+ pub pinned_specifier : Option < Rc < Specifier > > ,
6763 /// package.json files developed in the monorepo when variant is `SnappedTo`.
6864 /// Rc<RefCell<T>> for shared ownership with interior mutability.
6965 pub snapped_to_packages : Option < Vec < Rc < RefCell < PackageJson > > > > ,
@@ -76,7 +72,7 @@ impl Dependency {
7672 pub fn new (
7773 internal_name : String ,
7874 variant : VersionGroupVariant ,
79- pinned_specifier : Option < Specifier > ,
75+ pinned_specifier : Option < Rc < Specifier > > ,
8076 snapped_to_packages : Option < Vec < Rc < RefCell < PackageJson > > > > ,
8177 ) -> Dependency {
8278 Dependency {
@@ -125,18 +121,18 @@ impl Dependency {
125121 }
126122
127123 /// Set the expected version specifier to the given value
128- pub fn set_expected_specifier ( & self , specifier : & Specifier ) -> & Self {
129- * self . expected . borrow_mut ( ) = Some ( specifier . clone ( ) ) ;
124+ pub fn set_expected_specifier ( & self , specifier : & Rc < Specifier > ) -> & Self {
125+ * self . expected . borrow_mut ( ) = Some ( Rc :: clone ( specifier ) ) ;
130126 self
131127 }
132128
133129 /// Return the local instance's version specifier, if it exists
134- pub fn get_local_specifier ( & self ) -> Option < Specifier > {
130+ pub fn get_local_specifier ( & self ) -> Option < Rc < Specifier > > {
135131 self
136132 . local_instance
137133 . borrow ( )
138134 . as_ref ( )
139- . map ( |instance| instance. descriptor . specifier . clone ( ) )
135+ . map ( |instance| Rc :: clone ( & instance. descriptor . specifier ) )
140136 }
141137
142138 /// Whether the dependency name is a valid npm package name, is invalid, or
@@ -157,43 +153,42 @@ impl Dependency {
157153 /// Is this dependency a package developed in this repository, which has a
158154 /// missing or invalid .version property?
159155 pub fn has_local_instance_with_invalid_specifier ( & self ) -> bool {
160- self . get_local_specifier ( ) . is_some_and ( |local| {
161- if let Specifier :: BasicSemver ( semver) = local {
162- !matches ! ( semver. range_variant, SemverRange :: Exact )
163- } else {
164- true
165- }
166- } )
156+ self
157+ . get_local_specifier ( )
158+ . is_some_and ( |local| !matches ! ( & * local, Specifier :: Exact ( _) ) )
167159 }
168160
169161 /// Does every instance in this group have a specifier which is exactly the
170162 /// same?
171163 pub fn every_specifier_is_already_identical ( & self ) -> bool {
172164 if let Some ( first_actual) = self . instances . first ( ) . map ( |instance| & instance. descriptor . specifier ) {
173- self . instances . iter ( ) . all ( |instance| instance. descriptor . specifier == * first_actual)
165+ self . instances . iter ( ) . all ( |instance| {
166+ Rc :: ptr_eq ( & instance. descriptor . specifier , first_actual) || instance. descriptor . specifier . get_raw ( ) == first_actual. get_raw ( )
167+ } )
174168 } else {
175169 false
176170 }
177171 }
178172
179- pub fn get_unique_specifiers ( & self ) -> Vec < Specifier > {
173+ pub fn get_unique_specifiers ( & self ) -> Vec < Rc < Specifier > > {
180174 let mut unique_specifiers = Vec :: new ( ) ;
181175 for instance in self . instances . iter ( ) {
182- if !unique_specifiers. contains ( & instance. descriptor . specifier ) {
183- unique_specifiers. push ( instance. descriptor . specifier . clone ( ) ) ;
176+ let spec = & instance. descriptor . specifier ;
177+ if !unique_specifiers. iter ( ) . any ( |s : & Rc < Specifier > | s. get_raw ( ) == spec. get_raw ( ) ) {
178+ unique_specifiers. push ( Rc :: clone ( spec) ) ;
184179 }
185180 }
186181 unique_specifiers
187182 }
188183
189184 /// Get the highest (or lowest) semver specifier in this group.
190- pub fn get_highest_or_lowest_specifier ( & self ) -> Option < Specifier > {
185+ pub fn get_highest_or_lowest_specifier ( & self ) -> Option < Rc < Specifier > > {
191186 let prefer_highest = matches ! ( self . variant, VersionGroupVariant :: HighestSemver ) ;
192187 let preferred_order = if prefer_highest { Ordering :: Greater } else { Ordering :: Less } ;
193188 self
194189 . get_instances ( )
195190 . filter ( |instance| instance. descriptor . specifier . get_node_version ( ) . is_some ( ) )
196- . map ( |instance| instance. descriptor . specifier . clone ( ) )
191+ . map ( |instance| Rc :: clone ( & instance. descriptor . specifier ) )
197192 . fold ( None , |preferred, specifier| match preferred {
198193 None => Some ( specifier) ,
199194 Some ( preferred) => {
@@ -214,9 +209,9 @@ impl Dependency {
214209 ///
215210 /// When only applying eg. patch updates, some specifiers will be assigned to
216211 /// different updates if they are not on the same minor version.
217- pub fn get_eligible_registry_updates ( & self , ctx : & Context ) -> Option < HashMap < Specifier , Vec < Specifier > > > {
212+ pub fn get_eligible_registry_updates ( & self , ctx : & Context ) -> Option < HashMap < String , Vec < Rc < Specifier > > > > {
218213 ctx. updates_by_internal_name . get ( & self . internal_name ) . map ( |updates| {
219- let mut specifiers_by_eligible_update: HashMap < Specifier , Vec < Specifier > > = HashMap :: new ( ) ;
214+ let mut specifiers_by_eligible_update: HashMap < String , Vec < Rc < Specifier > > > = HashMap :: new ( ) ;
220215 self . get_unique_specifiers ( ) . iter ( ) . for_each ( |installed| {
221216 updates
222217 . iter ( )
@@ -234,8 +229,9 @@ impl Dependency {
234229 }
235230 } )
236231 . inspect ( |highest_update| {
237- let affected = specifiers_by_eligible_update. entry ( ( * highest_update) . clone ( ) ) . or_default ( ) ;
238- affected. push ( installed. clone ( ) ) ;
232+ let key = highest_update. get_raw ( ) . to_string ( ) ;
233+ let affected = specifiers_by_eligible_update. entry ( key) . or_default ( ) ;
234+ affected. push ( Rc :: clone ( installed) ) ;
239235 } ) ;
240236 } ) ;
241237 specifiers_by_eligible_update
@@ -250,13 +246,13 @@ impl Dependency {
250246 ///
251247 /// Even though the actual specifiers on disk might currently match, we should
252248 /// suggest it match what we the snapped to specifier should be once fixed
253- pub fn get_snapped_to_specifier ( & self , every_instance_in_the_project : & [ Rc < Instance > ] ) -> Option < Specifier > {
249+ pub fn get_snapped_to_specifier ( & self , every_instance_in_the_project : & [ Rc < Instance > ] ) -> Option < Rc < Specifier > > {
254250 if let Some ( snapped_to_packages) = & self . snapped_to_packages {
255251 for instance in every_instance_in_the_project {
256252 if * instance. descriptor . internal_name == * self . internal_name {
257253 for snapped_to_package in snapped_to_packages {
258254 if instance. descriptor . package . borrow ( ) . name == snapped_to_package. borrow ( ) . name {
259- return Some ( instance. descriptor . specifier . clone ( ) ) ;
255+ return Some ( Rc :: clone ( & instance. descriptor . specifier ) ) ;
260256 }
261257 }
262258 }
0 commit comments