11use std:: {
2- borrow:: Borrow ,
32 cmp:: Ordering ,
43 collections:: HashMap ,
54 fs:: { read_link, remove_dir_all} ,
@@ -12,6 +11,29 @@ use serde::Deserialize;
1211
1312use crate :: { utils, Config } ;
1413
14+ #[ cfg( target_os = "windows" ) ]
15+ const PLATFORM : & str = "win" ;
16+ #[ cfg( target_os = "macos" ) ]
17+ const PLATFORM : & str = "darwin" ;
18+ #[ cfg( target_os = "linux" ) ]
19+ const PLATFORM : & str = "linux" ;
20+
21+ #[ cfg( target_os = "windows" ) ]
22+ const EXT : & str = ".zip" ;
23+ #[ cfg( target_os = "macos" ) ]
24+ const EXT : & str = ".tar.gz" ;
25+ #[ cfg( target_os = "linux" ) ]
26+ const EXT : & str = ".tar.gz" ;
27+
28+ #[ cfg( target_arch = "x86_64" ) ]
29+ const ARCH : & str = "x64" ;
30+ #[ cfg( target_arch = "x86" ) ]
31+ const ARCH : & str = "x86" ;
32+ #[ cfg( target_arch = "aarch64" ) ]
33+ const ARCH : & str = "arm64" ;
34+
35+ const X64 : & str = "x64" ;
36+
1537pub trait NodeVersion {
1638 fn version ( & self ) -> & Version ;
1739}
@@ -68,7 +90,7 @@ fn parse_version_str(version_str: &str) -> Result<Version> {
6890 let clean_version = if version_str. starts_with ( 'v' ) {
6991 version_str. get ( 1 ..) . unwrap ( )
7092 } else {
71- version_str. borrow ( )
93+ version_str
7294 } ;
7395
7496 Version :: parse ( clean_version) . context ( version_str. to_owned ( ) )
@@ -99,35 +121,40 @@ impl OnlineNodeVersion {
99121 }
100122
101123 pub fn download_url ( & self ) -> String {
102- let file_name = self . file ( ) ;
124+ let file_name: String ;
125+
126+ #[ cfg( target_os = "macos" ) ]
127+ {
128+ let has_arm = self . has_arm ( ) ;
129+
130+ file_name = self . file ( !has_arm) ;
131+ }
132+
133+ #[ cfg( not( target_os = "macos" ) ) ]
134+ {
135+ file_name = self . file ( false ) ;
136+ }
103137
104138 format ! ( "https://nodejs.org/dist/v{}/{}" , self . version, file_name)
105139 }
106140
107- #[ cfg( target_os = "windows" ) ]
108- fn file ( & self ) -> String {
141+ fn file ( & self , force_x64 : bool ) -> String {
109142 format ! (
110- "node-v{version}-win-{arch}.zip" ,
111- version = self . version( ) ,
112- arch = if cfg!( target_arch = "x86" ) {
113- "x86"
114- } else {
115- "x64"
116- } ,
143+ "node-v{VERSION}-{PLATFORM}-{ARCH}{EXT}" ,
144+ VERSION = self . version( ) ,
145+ ARCH = if force_x64 { X64 } else { ARCH } ,
117146 )
118147 }
119148
120149 #[ cfg( target_os = "macos" ) ]
121- fn file ( & self ) -> String {
122- format ! (
123- "node-v{version}-darwin-x64.tar.gz" ,
124- version = self . version ( )
125- )
126- }
150+ fn has_arm ( & self ) -> bool {
151+ for file in self . files . iter ( ) {
152+ if file . contains ( "osx" ) && file . contains ( "arm64" ) {
153+ return true ;
154+ }
155+ }
127156
128- #[ cfg( target_os = "linux" ) ]
129- fn file ( & self ) -> String {
130- format ! ( "node-v{version}-linux-x64.tar.gz" , version = self . version( ) )
157+ false
131158 }
132159}
133160
@@ -253,7 +280,7 @@ impl InstalledNodeVersion {
253280 pub fn find_matching ( config : & Config , range : & Range ) -> Option < InstalledNodeVersion > {
254281 Self :: list ( config)
255282 . iter ( )
256- . find ( |inv| range. satisfies ( inv. version ( ) . borrow ( ) ) )
283+ . find ( |inv| range. satisfies ( inv. version ( ) ) )
257284 . map ( |inv| inv. to_owned ( ) )
258285 }
259286}
@@ -276,6 +303,8 @@ mod tests {
276303 use anyhow:: Result ;
277304 use node_semver:: Version ;
278305
306+ use spectral:: prelude:: * ;
307+
279308 use crate :: node_version:: OnlineNodeVersion ;
280309
281310 #[ test]
@@ -350,7 +379,7 @@ mod tests {
350379 let result: OnlineNodeVersion = serde_json:: from_str ( json_str)
351380 . expect ( "Failed to parse version data from nodejs.org" ) ;
352381
353- assert_eq ! ( expected, result) ;
382+ assert_that ! ( expected) . is_equal_to ( result) ;
354383
355384 Ok ( ( ) )
356385 }
0 commit comments