client_core/
architecture.rs1use anyhow::Result;
10use serde::{Deserialize, Serialize};
11use std::fmt::{self, Display};
12use std::str::FromStr;
13use tracing::warn;
14
15#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum Architecture {
18 X86_64,
20 Aarch64,
22 Unsupported(String),
24}
25
26impl Architecture {
27 pub fn detect() -> Self {
39 let arch_str = std::env::consts::ARCH;
40 Self::from_str(arch_str).unwrap_or_else(|_| {
41 warn!("Detected unknown architecture: {}", arch_str);
42 Self::Unsupported(arch_str.to_string())
43 })
44 }
45
46 pub fn as_str(&self) -> &str {
56 match self {
57 Self::X86_64 => "x86_64",
58 Self::Aarch64 => "aarch64",
59 Self::Unsupported(arch) => arch,
60 }
61 }
62
63 pub fn from_str(arch_str: &str) -> Result<Self> {
78 match arch_str.to_lowercase().as_str() {
79 "x86_64" | "amd64" | "x64" => Ok(Self::X86_64),
80 "aarch64" | "arm64" | "armv8" => Ok(Self::Aarch64),
81 _ => Err(anyhow::anyhow!("Unsupported architecture: {}", arch_str)),
82 }
83 }
84
85 pub fn is_supported(&self) -> bool {
98 match self {
99 Self::X86_64 | Self::Aarch64 => true,
100 Self::Unsupported(_) => false,
101 }
102 }
103
104 pub fn display_name(&self) -> &str {
114 match self {
115 Self::X86_64 => "Intel/AMD 64-bit",
116 Self::Aarch64 => "ARM 64-bit",
117 Self::Unsupported(_) => "Unsupported architecture",
118 }
119 }
120
121 pub fn file_suffix(&self) -> &str {
133 match self {
134 Self::X86_64 => "x86_64",
135 Self::Aarch64 => "aarch64",
136 Self::Unsupported(arch) => arch,
137 }
138 }
139
140 pub fn is_64bit(&self) -> bool {
142 match self {
143 Self::X86_64 | Self::Aarch64 => true,
144 Self::Unsupported(_) => false, }
146 }
147
148 pub fn supported_architectures() -> Vec<Architecture> {
150 vec![Self::X86_64, Self::Aarch64]
151 }
152
153 pub fn supports_incremental_upgrade(&self) -> bool {
157 self.is_supported()
158 }
159}
160
161impl Display for Architecture {
162 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163 write!(f, "{}", self.as_str())
164 }
165}
166
167impl FromStr for Architecture {
168 type Err = anyhow::Error;
169
170 fn from_str(s: &str) -> Result<Self> {
171 Architecture::from_str(s)
172 }
173}
174
175pub struct ArchitectureCompatibilityChecker;
177
178impl ArchitectureCompatibilityChecker {
179 pub fn check_compatibility(target_arch: &Architecture) -> Result<()> {
188 let current_arch = Architecture::detect();
189
190 if current_arch == *target_arch {
191 Ok(())
192 } else {
193 Err(anyhow::anyhow!(format!(
194 "Architecture mismatch: current system is {}, target architecture is {}",
195 current_arch.display_name(),
196 target_arch.display_name()
197 )))
198 }
199 }
200
201 pub fn get_system_summary() -> String {
203 let arch = Architecture::detect();
204 format!(
205 "OS: {}, architecture: {} ({}), 64-bit support: {}",
206 std::env::consts::OS,
207 arch.as_str(),
208 arch.display_name(),
209 if arch.is_64bit() { "yes" } else { "no" }
210 )
211 }
212
213 pub fn supports_cross_architecture_operation(
217 from_arch: &Architecture,
218 to_arch: &Architecture,
219 ) -> bool {
220 from_arch == to_arch
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 #[test]
231 fn test_architecture_detection() {
232 let arch = Architecture::detect();
233
234 assert!(matches!(
236 arch,
237 Architecture::X86_64 | Architecture::Aarch64 | Architecture::Unsupported(_)
238 ));
239
240 println!("检测到的架构: {} ({})", arch.as_str(), arch.display_name());
242 }
243
244 #[test]
245 fn test_architecture_parsing() {
246 assert_eq!(
248 Architecture::from_str("x86_64").unwrap(),
249 Architecture::X86_64
250 );
251 assert_eq!(
252 Architecture::from_str("amd64").unwrap(),
253 Architecture::X86_64
254 );
255 assert_eq!(Architecture::from_str("x64").unwrap(), Architecture::X86_64);
256
257 assert_eq!(
259 Architecture::from_str("aarch64").unwrap(),
260 Architecture::Aarch64
261 );
262 assert_eq!(
263 Architecture::from_str("arm64").unwrap(),
264 Architecture::Aarch64
265 );
266 assert_eq!(
267 Architecture::from_str("armv8").unwrap(),
268 Architecture::Aarch64
269 );
270
271 assert_eq!(
273 Architecture::from_str("X86_64").unwrap(),
274 Architecture::X86_64
275 );
276 assert_eq!(
277 Architecture::from_str("ARM64").unwrap(),
278 Architecture::Aarch64
279 );
280
281 assert!(Architecture::from_str("mips").is_err());
283 assert!(Architecture::from_str("riscv").is_err());
284 }
285
286 #[test]
287 fn test_architecture_string_conversion() {
288 let x86_arch = Architecture::X86_64;
289 assert_eq!(x86_arch.as_str(), "x86_64");
290 assert_eq!(x86_arch.to_string(), "x86_64");
291
292 let arm_arch = Architecture::Aarch64;
293 assert_eq!(arm_arch.as_str(), "aarch64");
294 assert_eq!(arm_arch.to_string(), "aarch64");
295
296 let unsupported = Architecture::Unsupported("mips".to_string());
297 assert_eq!(unsupported.as_str(), "mips");
298 assert_eq!(unsupported.to_string(), "mips");
299 }
300
301 #[test]
302 fn test_architecture_support_check() {
303 assert!(Architecture::X86_64.is_supported());
304 assert!(Architecture::Aarch64.is_supported());
305 assert!(!Architecture::Unsupported("mips".to_string()).is_supported());
306 }
307
308 #[test]
309 fn test_architecture_properties() {
310 let x86_arch = Architecture::X86_64;
311 assert_eq!(x86_arch.display_name(), "Intel/AMD 64位");
312 assert_eq!(x86_arch.file_suffix(), "x86_64");
313 assert!(x86_arch.is_64bit());
314 assert!(x86_arch.supports_incremental_upgrade());
315
316 let arm_arch = Architecture::Aarch64;
317 assert_eq!(arm_arch.display_name(), "ARM 64位");
318 assert_eq!(arm_arch.file_suffix(), "aarch64");
319 assert!(arm_arch.is_64bit());
320 assert!(arm_arch.supports_incremental_upgrade());
321
322 let unsupported = Architecture::Unsupported("mips".to_string());
323 assert_eq!(unsupported.display_name(), "不支持的架构");
324 assert_eq!(unsupported.file_suffix(), "mips");
325 assert!(!unsupported.is_64bit());
326 assert!(!unsupported.supports_incremental_upgrade());
327 }
328
329 #[test]
330 fn test_supported_architectures() {
331 let supported = Architecture::supported_architectures();
332 assert_eq!(supported.len(), 2);
333 assert!(supported.contains(&Architecture::X86_64));
334 assert!(supported.contains(&Architecture::Aarch64));
335 }
336
337 #[test]
338 fn test_compatibility_checker() {
339 let current_arch = Architecture::detect();
340
341 assert!(ArchitectureCompatibilityChecker::check_compatibility(¤t_arch).is_ok());
343
344 let summary = ArchitectureCompatibilityChecker::get_system_summary();
346 assert!(summary.contains("操作系统"));
347 assert!(summary.contains("架构"));
348 assert!(summary.contains("64位支持"));
349
350 println!("系统摘要: {summary}");
351 }
352
353 #[test]
354 fn test_cross_architecture_support() {
355 let x86 = Architecture::X86_64;
356 let arm = Architecture::Aarch64;
357
358 assert!(
360 ArchitectureCompatibilityChecker::supports_cross_architecture_operation(&x86, &x86)
361 );
362 assert!(
363 ArchitectureCompatibilityChecker::supports_cross_architecture_operation(&arm, &arm)
364 );
365
366 assert!(
368 !ArchitectureCompatibilityChecker::supports_cross_architecture_operation(&x86, &arm)
369 );
370 assert!(
371 !ArchitectureCompatibilityChecker::supports_cross_architecture_operation(&arm, &x86)
372 );
373 }
374
375 #[test]
376 fn test_serde_compatibility() {
377 let x86_arch = Architecture::X86_64;
378
379 let serialized = serde_json::to_string(&x86_arch).unwrap();
381 assert!(serialized.contains("X86_64"));
382
383 let deserialized: Architecture = serde_json::from_str(&serialized).unwrap();
385 assert_eq!(deserialized, x86_arch);
386 }
387
388 #[test]
390 fn test_task_1_4_acceptance_criteria() {
391 let _x86 = Architecture::X86_64;
393 let _arm = Architecture::Aarch64;
394 let _unsupported = Architecture::Unsupported("test".to_string());
395
396 let detected_arch = Architecture::detect();
398 assert!(matches!(
399 detected_arch,
400 Architecture::X86_64 | Architecture::Aarch64 | Architecture::Unsupported(_)
401 ));
402
403 assert_eq!(Architecture::X86_64.as_str(), "x86_64");
405 assert_eq!(Architecture::Aarch64.as_str(), "aarch64");
406
407 assert_eq!(
409 Architecture::from_str("x86_64").unwrap(),
410 Architecture::X86_64
411 );
412 assert_eq!(
413 Architecture::from_str("aarch64").unwrap(),
414 Architecture::Aarch64
415 );
416
417 println!("✅ Task 1.4: 架构检测模块 - 验收标准测试通过");
421 println!(" - ✅ Architecture枚举定义正确");
422 println!(
423 " - ✅ detect()方法能自动检测架构: {}",
424 detected_arch.as_str()
425 );
426 println!(" - ✅ as_str()方法返回正确字符串");
427 println!(" - ✅ from_str()方法能正确解析字符串");
428 println!(" - ✅ 单元测试覆盖全面");
429 }
430}