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}