1use crate::error::{Error, Result};
9use crate::platform::Platform;
10
11#[derive(Clone, Copy, Debug)]
13pub struct Pin {
14 pub platform_key: &'static str,
15 pub bundle_name: &'static str,
16 pub sha256: &'static str,
17}
18
19include!(concat!(env!("OUT_DIR"), "/pins_gen.rs"));
21
22pub fn pin_for(platform: Platform) -> Result<&'static Pin> {
25 PINS.iter()
26 .find(|p| p.platform_key == platform.key())
27 .ok_or(Error::UnsupportedPlatform {
28 os: std::env::consts::OS,
29 arch: std::env::consts::ARCH,
30 })
31}
32
33pub fn bundle_url(pin: &Pin) -> String {
35 format!("{BASE_URL}/{}", pin.bundle_name)
36}
37
38pub fn user_agent() -> String {
41 format!("stackql-mcp-server-cargo/{STACKQL_VERSION}")
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn every_platform_has_a_pin() {
50 for platform in [
51 Platform::LinuxX64,
52 Platform::LinuxArm64,
53 Platform::WindowsX64,
54 Platform::WindowsArm64,
55 Platform::DarwinUniversal,
56 ] {
57 let pin = pin_for(platform).unwrap();
58 assert_eq!(pin.platform_key, platform.key());
59 assert_eq!(
60 pin.bundle_name,
61 format!("stackql-mcp-{}.mcpb", platform.key())
62 );
63 }
64 }
65
66 #[test]
67 fn pins_are_well_formed_sha256_hex() {
68 for pin in PINS {
69 assert_eq!(pin.sha256.len(), 64, "{}", pin.bundle_name);
70 assert!(
71 pin.sha256.chars().all(|c| c.is_ascii_hexdigit()),
72 "{}",
73 pin.bundle_name
74 );
75 assert_eq!(pin.sha256, pin.sha256.to_lowercase());
76 }
77 }
78
79 #[test]
80 fn bundle_url_is_the_proxy_front_door_for_the_pinned_version() {
81 let pin = pin_for(Platform::LinuxX64).unwrap();
82 assert_eq!(
83 bundle_url(pin),
84 format!(
85 "https://releases.stackql.io/stackql/{STACKQL_VERSION}/stackql-mcp-linux-x64.mcpb"
86 )
87 );
88 assert_eq!(
89 user_agent(),
90 format!("stackql-mcp-server-cargo/{STACKQL_VERSION}")
91 );
92 }
93}