Skip to main content

stackql_mcp/
platform.rs

1use crate::error::{Error, Result};
2
3/// A platform the packaging repo publishes a .mcpb bundle for.
4///
5/// Keys mirror stackql/stackql packaging/mcpb: linux-x64, linux-arm64,
6/// windows-x64, windows-arm64, darwin-universal.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum Platform {
9    LinuxX64,
10    LinuxArm64,
11    WindowsX64,
12    WindowsArm64,
13    DarwinUniversal,
14}
15
16impl Platform {
17    /// Detect the host platform, or fail if no bundle is published for it.
18    pub fn detect() -> Result<Self> {
19        Self::from_os_arch(std::env::consts::OS, std::env::consts::ARCH)
20    }
21
22    pub(crate) fn from_os_arch(os: &'static str, arch: &'static str) -> Result<Self> {
23        match (os, arch) {
24            ("linux", "x86_64") => Ok(Platform::LinuxX64),
25            ("linux", "aarch64") => Ok(Platform::LinuxArm64),
26            ("windows", "x86_64") => Ok(Platform::WindowsX64),
27            ("windows", "aarch64") => Ok(Platform::WindowsArm64),
28            // The darwin bundle is a universal binary, so any macOS arch works.
29            ("macos", _) => Ok(Platform::DarwinUniversal),
30            _ => Err(Error::UnsupportedPlatform { os, arch }),
31        }
32    }
33
34    /// The platform key used in bundle names and cache paths.
35    pub fn key(self) -> &'static str {
36        match self {
37            Platform::LinuxX64 => "linux-x64",
38            Platform::LinuxArm64 => "linux-arm64",
39            Platform::WindowsX64 => "windows-x64",
40            Platform::WindowsArm64 => "windows-arm64",
41            Platform::DarwinUniversal => "darwin-universal",
42        }
43    }
44
45    /// Name of the server binary inside the bundle's server/ directory.
46    pub fn binary_name(self) -> &'static str {
47        match self {
48            Platform::WindowsX64 | Platform::WindowsArm64 => "stackql.exe",
49            _ => "stackql",
50        }
51    }
52}
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn known_platforms_map_to_keys() {
60        assert_eq!(
61            Platform::from_os_arch("linux", "x86_64").unwrap().key(),
62            "linux-x64"
63        );
64        assert_eq!(
65            Platform::from_os_arch("linux", "aarch64").unwrap().key(),
66            "linux-arm64"
67        );
68        assert_eq!(
69            Platform::from_os_arch("windows", "x86_64").unwrap().key(),
70            "windows-x64"
71        );
72        assert_eq!(
73            Platform::from_os_arch("windows", "aarch64").unwrap().key(),
74            "windows-arm64"
75        );
76        assert_eq!(
77            Platform::from_os_arch("macos", "aarch64").unwrap().key(),
78            "darwin-universal"
79        );
80        assert_eq!(
81            Platform::from_os_arch("macos", "x86_64").unwrap().key(),
82            "darwin-universal"
83        );
84    }
85
86    #[test]
87    fn unsupported_platform_is_an_error() {
88        assert!(Platform::from_os_arch("freebsd", "x86_64").is_err());
89        assert!(Platform::from_os_arch("windows", "x86").is_err());
90    }
91
92    #[test]
93    fn windows_binary_has_exe_suffix() {
94        assert_eq!(Platform::WindowsX64.binary_name(), "stackql.exe");
95        assert_eq!(Platform::WindowsArm64.binary_name(), "stackql.exe");
96        assert_eq!(Platform::LinuxX64.binary_name(), "stackql");
97    }
98}