Skip to main content

pi/
platform.rs

1//! Shared platform-identity utilities.
2//!
3//! Provides OS name, architecture, and client identity strings used by
4//! provider request builders. Centralises the mapping from Rust's
5//! `std::env::consts` values to the provider-expected naming conventions
6//! (e.g. `darwin` instead of `macos`, `arm64` instead of `aarch64`).
7
8/// Crate version baked in at compile time.
9pub const VERSION: &str = env!("CARGO_PKG_VERSION");
10
11// ---------------------------------------------------------------------------
12// OS
13// ---------------------------------------------------------------------------
14
15/// Return the OS name in the format most providers expect.
16///
17/// Maps Rust's `std::env::consts::OS`:
18///   - `"macos"` → `"darwin"`
19///   - everything else passed through (`"linux"`, `"windows"`, …)
20#[inline]
21pub fn os_name() -> &'static str {
22    match std::env::consts::OS {
23        "macos" => "darwin",
24        other => other,
25    }
26}
27
28// ---------------------------------------------------------------------------
29// Architecture
30// ---------------------------------------------------------------------------
31
32/// Return the architecture name in the format most providers expect.
33///
34/// Maps Rust's `std::env::consts::ARCH`:
35///   - `"aarch64"` → `"arm64"`
36///   - `"x86_64"`  → `"amd64"`
37///   - everything else passed through
38#[inline]
39pub fn arch_name() -> &'static str {
40    match std::env::consts::ARCH {
41        "aarch64" => "arm64",
42        "x86_64" => "amd64",
43        other => other,
44    }
45}
46
47// ---------------------------------------------------------------------------
48// Composite helpers
49// ---------------------------------------------------------------------------
50
51/// `"{os}/{arch}"` — e.g. `"linux/amd64"`, `"darwin/arm64"`.
52pub fn platform_tag() -> String {
53    format!("{}/{}", os_name(), arch_name())
54}
55
56/// Canonical Pi User-Agent: `"pi_agent_rust/{version}"`.
57pub fn pi_user_agent() -> String {
58    format!("pi_agent_rust/{VERSION}")
59}
60
61/// Canonical Pi User-Agent with an additional component:
62/// `"pi_agent_rust/{version} {extra}"`.
63pub fn pi_user_agent_with(extra: &str) -> String {
64    format!("pi_agent_rust/{VERSION} {extra}")
65}
66
67// ---------------------------------------------------------------------------
68// Tests
69// ---------------------------------------------------------------------------
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn os_name_not_empty() {
77        assert!(!os_name().is_empty());
78    }
79
80    #[test]
81    fn arch_name_not_empty() {
82        assert!(!arch_name().is_empty());
83    }
84
85    #[test]
86    fn platform_tag_has_slash() {
87        let tag = platform_tag();
88        assert!(tag.contains('/'), "expected OS/ARCH, got: {tag}");
89    }
90
91    #[test]
92    fn pi_user_agent_contains_version() {
93        let ua = pi_user_agent();
94        assert!(ua.starts_with("pi_agent_rust/"), "ua: {ua}");
95        assert!(ua.contains(VERSION), "ua should contain version");
96    }
97
98    #[test]
99    fn pi_user_agent_with_appends() {
100        let ua = pi_user_agent_with("Antigravity/1.2.3");
101        assert!(ua.starts_with("pi_agent_rust/"));
102        assert!(ua.ends_with("Antigravity/1.2.3"));
103    }
104
105    #[cfg(target_os = "linux")]
106    #[test]
107    fn linux_os_name() {
108        assert_eq!(os_name(), "linux");
109    }
110
111    #[cfg(target_os = "macos")]
112    #[test]
113    fn macos_maps_to_darwin() {
114        assert_eq!(os_name(), "darwin");
115    }
116
117    #[cfg(target_arch = "x86_64")]
118    #[test]
119    fn x86_64_maps_to_amd64() {
120        assert_eq!(arch_name(), "amd64");
121    }
122
123    #[cfg(target_arch = "aarch64")]
124    #[test]
125    fn aarch64_maps_to_arm64() {
126        assert_eq!(arch_name(), "arm64");
127    }
128}