Skip to main content

hyperdb_bootstrap/
platform.rs

1// Copyright (c) 2026, Salesforce, Inc. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4//! Host-platform detection and slug encoding for the four targets that
5//! Tableau's Hyper C++ API ships binaries for.
6
7use serde::{Deserialize, Serialize};
8use std::fmt;
9
10use crate::Error;
11
12/// One of the four platforms that Tableau publishes a `hyperd` build for.
13///
14/// The variant names encode both OS and architecture and map 1:1 to the
15/// slugs used in the release URL structure and in `hyperd-version.toml`.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "kebab-case")]
18pub enum Platform {
19    /// Apple Silicon macOS (`aarch64-apple-darwin`).
20    #[serde(rename = "macos-arm64")]
21    MacosArm64,
22    /// Intel macOS (`x86_64-apple-darwin`).
23    #[serde(rename = "macos-x86_64")]
24    MacosX86_64,
25    /// 64-bit Linux (`x86_64-unknown-linux-gnu`).
26    #[serde(rename = "linux-x86_64")]
27    LinuxX86_64,
28    /// 64-bit Windows (`x86_64-pc-windows-msvc`).
29    #[serde(rename = "windows-x86_64")]
30    WindowsX86_64,
31}
32
33impl Platform {
34    /// Detects the current host's platform.
35    ///
36    /// Uses `std::env::consts::OS` and `std::env::consts::ARCH`. Returns
37    /// [`Error::UnsupportedPlatform`] for any combination that has no
38    /// published `hyperd` build.
39    ///
40    /// # Errors
41    ///
42    /// Returns [`Error::UnsupportedPlatform`] when the host OS/arch pair
43    /// does not match one of the four supported targets.
44    pub fn current() -> Result<Self, Error> {
45        let os = std::env::consts::OS;
46        let arch = std::env::consts::ARCH;
47        match (os, arch) {
48            ("macos", "aarch64") => Ok(Self::MacosArm64),
49            ("macos", "x86_64") => Ok(Self::MacosX86_64),
50            ("linux", "x86_64") => Ok(Self::LinuxX86_64),
51            ("windows", "x86_64") => Ok(Self::WindowsX86_64),
52            _ => Err(Error::UnsupportedPlatform {
53                os: os.to_string(),
54                arch: arch.to_string(),
55            }),
56        }
57    }
58
59    /// Returns the kebab-case slug used in release URLs and version metadata
60    /// (for example, `"macos-arm64"`).
61    #[must_use]
62    pub fn slug(self) -> &'static str {
63        match self {
64            Self::MacosArm64 => "macos-arm64",
65            Self::MacosX86_64 => "macos-x86_64",
66            Self::LinuxX86_64 => "linux-x86_64",
67            Self::WindowsX86_64 => "windows-x86_64",
68        }
69    }
70
71    /// Returns the file name of the `hyperd` executable on this platform
72    /// (`"hyperd.exe"` on Windows, `"hyperd"` elsewhere).
73    #[must_use]
74    pub fn executable_name(self) -> &'static str {
75        match self {
76            Self::WindowsX86_64 => "hyperd.exe",
77            _ => "hyperd",
78        }
79    }
80}
81
82impl fmt::Display for Platform {
83    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84        f.write_str(self.slug())
85    }
86}
87
88impl std::str::FromStr for Platform {
89    type Err = Error;
90
91    fn from_str(s: &str) -> Result<Self, Self::Err> {
92        match s {
93            "macos-arm64" => Ok(Self::MacosArm64),
94            "macos-x86_64" => Ok(Self::MacosX86_64),
95            "linux-x86_64" => Ok(Self::LinuxX86_64),
96            "windows-x86_64" => Ok(Self::WindowsX86_64),
97            other => Err(Error::UnknownPlatformSlug(other.to_string())),
98        }
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use super::*;
105
106    #[test]
107    fn slug_roundtrip() {
108        for p in [
109            Platform::MacosArm64,
110            Platform::MacosX86_64,
111            Platform::LinuxX86_64,
112            Platform::WindowsX86_64,
113        ] {
114            assert_eq!(p.slug().parse::<Platform>().unwrap(), p);
115        }
116    }
117
118    #[test]
119    fn executable_name_windows() {
120        assert_eq!(Platform::WindowsX86_64.executable_name(), "hyperd.exe");
121        assert_eq!(Platform::LinuxX86_64.executable_name(), "hyperd");
122    }
123}