1use std::path::PathBuf;
7use vx_installer::{ArchiveFormat, InstallConfig, InstallMethod};
8use vx_tool_standard::{StandardToolConfig, StandardUrlBuilder, ToolDependency};
9
10pub struct Config;
12
13#[derive(Debug, Clone)]
15pub struct RustUrlBuilder;
16
17impl Default for RustUrlBuilder {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl RustUrlBuilder {
24 pub fn new() -> Self {
25 Self
26 }
27}
28
29impl StandardUrlBuilder for RustUrlBuilder {
30 fn download_url(version: &str) -> Option<String> {
32 let filename = Self::get_filename(version);
33
34 Some(format!(
35 "https://forge.rust-lang.org/infra/channel-releases.html#{}",
36 filename
37 ))
38 }
39
40 fn get_filename(version: &str) -> String {
42 let platform = Self::get_platform_string();
43 if cfg!(windows) {
44 format!("rust-{}-{}.msi", version, platform)
45 } else {
46 format!("rust-{}-{}.tar.gz", version, platform)
47 }
48 }
49
50 fn get_platform_string() -> String {
52 if cfg!(target_os = "windows") {
53 if cfg!(target_arch = "x86_64") {
54 "x86_64-pc-windows-msvc".to_string()
55 } else if cfg!(target_arch = "x86") {
56 "i686-pc-windows-msvc".to_string()
57 } else {
58 "unknown-pc-windows-msvc".to_string()
59 }
60 } else if cfg!(target_os = "macos") {
61 if cfg!(target_arch = "x86_64") {
62 "x86_64-apple-darwin".to_string()
63 } else if cfg!(target_arch = "aarch64") {
64 "aarch64-apple-darwin".to_string()
65 } else {
66 "unknown-apple-darwin".to_string()
67 }
68 } else if cfg!(target_os = "linux") {
69 if cfg!(target_arch = "x86_64") {
70 "x86_64-unknown-linux-gnu".to_string()
71 } else if cfg!(target_arch = "aarch64") {
72 "aarch64-unknown-linux-gnu".to_string()
73 } else {
74 "unknown-unknown-linux-gnu".to_string()
75 }
76 } else {
77 "unknown".to_string()
78 }
79 }
80}
81
82impl StandardToolConfig for Config {
83 fn tool_name() -> &'static str {
84 "rust"
85 }
86
87 fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
88 create_install_config(version, install_dir)
89 }
90
91 fn get_install_methods() -> Vec<String> {
92 vec!["archive".to_string(), "installer".to_string()]
93 }
94
95 fn supports_auto_install() -> bool {
96 true
97 }
98
99 fn get_manual_instructions() -> String {
100 "Visit https://rustup.rs/ to install Rust manually".to_string()
101 }
102
103 fn get_dependencies() -> Vec<ToolDependency> {
104 vec![]
105 }
106
107 fn get_default_version() -> &'static str {
108 "stable"
109 }
110}
111
112pub fn create_install_config(version: &str, install_dir: PathBuf) -> InstallConfig {
114 let download_url = RustUrlBuilder::download_url(version);
115
116 InstallConfig::builder()
117 .tool_name(Config::tool_name())
118 .version(version)
119 .download_url(download_url.unwrap_or_default())
120 .install_method(InstallMethod::Archive {
121 format: if cfg!(windows) {
122 ArchiveFormat::Zip
123 } else {
124 ArchiveFormat::TarGz
125 },
126 })
127 .install_dir(install_dir)
128 .build()
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn test_rust_url_builder() {
137 let url = RustUrlBuilder::download_url("1.75.0");
138 assert!(url.is_some());
139 assert!(url.unwrap().contains("rust-lang.org"));
140 }
141
142 #[test]
143 fn test_platform_string() {
144 let platform = RustUrlBuilder::get_platform_string();
145 assert!(!platform.is_empty());
146 }
147
148 #[test]
149 fn test_create_install_config() {
150 let config = create_install_config("1.75.0", PathBuf::from("/tmp/rust"));
151 assert_eq!(config.tool_name, "rust");
152 assert_eq!(config.version, "1.75.0");
153 assert!(config.download_url.is_some());
154 }
155}