Skip to main content

tidepool_gvm/
platform.rs

1//! Cross-platform compatibility module
2//!
3//! Provides unified platform detection and related utility functions.
4
5/// Platform information structure
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct PlatformInfo {
8    pub os: String,
9    pub arch: String,
10    pub extension: String,
11}
12
13impl PlatformInfo {
14    /// Automatically detects the current platform information
15    pub fn detect() -> Self {
16        let (os, arch) = detect_os_arch();
17        let extension = detect_archive_extension();
18
19        Self { os: os.to_string(), arch: arch.to_string(), extension: extension.to_string() }
20    }
21
22    /// Generates the Go archive filename
23    pub fn archive_filename(&self, version: &str) -> String {
24        format!("go{}.{}-{}.{}", version, self.os, self.arch, self.extension)
25    }
26
27    /// Gets the Go executable filename (including platform-specific extension)
28    pub fn go_executable_name() -> &'static str {
29        if cfg!(target_os = "windows") {
30            "go.exe"
31        } else {
32            "go"
33        }
34    }
35}
36
37impl Default for PlatformInfo {
38    fn default() -> Self {
39        Self::detect()
40    }
41}
42
43/// Detects the operating system and architecture
44fn detect_os_arch() -> (&'static str, &'static str) {
45    let os = match std::env::consts::OS {
46        "linux" => "linux",
47        "macos" => "darwin",
48        "windows" => "windows",
49        _ => "linux", // Default to linux
50    };
51
52    let arch = match std::env::consts::ARCH {
53        "x86_64" => "amd64",
54        "x86" => "386",
55        "aarch64" => "arm64",
56        "arm" => "armv6l",
57        _ => "amd64", // Default to amd64
58    };
59
60    (os, arch)
61}
62
63/// Detects the archive file extension
64fn detect_archive_extension() -> &'static str {
65    if cfg!(target_os = "windows") {
66        "zip"
67    } else {
68        "tar.gz"
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_platform_detection() {
78        let platform = PlatformInfo::detect();
79        assert!(!platform.os.is_empty());
80        assert!(!platform.arch.is_empty());
81        assert!(!platform.extension.is_empty());
82    }
83
84    #[test]
85    fn test_archive_filename() {
86        let platform = PlatformInfo::detect();
87        let filename = platform.archive_filename("1.21.0");
88        assert!(filename.starts_with("go1.21.0."));
89        assert!(filename.contains(&platform.os));
90        assert!(filename.contains(&platform.arch));
91        assert!(filename.ends_with(&platform.extension));
92    }
93
94    #[test]
95    fn test_go_executable_name() {
96        let exe_name = PlatformInfo::go_executable_name();
97        if cfg!(target_os = "windows") {
98            assert_eq!(exe_name, "go.exe");
99        } else {
100            assert_eq!(exe_name, "go");
101        }
102    }
103}