use std::sync::OnceLock;
#[cfg(all(target_os = "linux", target_env = "musl"))]
const PLATFORM_LIBC: &str = "musl";
#[cfg(all(target_os = "linux", target_env = "gnu"))]
const PLATFORM_LIBC: &str = "glibc";
#[cfg(target_os = "macos")]
const PLATFORM_LIBC: &str = "darwin";
#[cfg(target_os = "windows")]
const PLATFORM_LIBC: &str = "windows";
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
const PLATFORM_LIBC: &str = "unknown";
static CACHED_PLATFORM: OnceLock<(String, String, String)> = OnceLock::new();
pub fn get_platform_libc() -> &'static str {
PLATFORM_LIBC
}
pub fn get_foojay_libc_type() -> &'static str {
match PLATFORM_LIBC {
"musl" => "musl",
"glibc" => "glibc", "darwin" => "libc", "windows" => "c_std_lib", _ => "libc", }
}
pub fn matches_foojay_libc_type(foojay_libc: &str) -> bool {
match (PLATFORM_LIBC, foojay_libc) {
("musl", "musl") => true,
("glibc", "libc") | ("glibc", "glibc") => true,
("darwin", "libc") => true, ("windows", "c_std_lib") => true, _ => false,
}
}
pub fn get_required_libc_type() -> &'static str {
get_foojay_libc_type()
}
pub fn get_platform_description() -> String {
match PLATFORM_LIBC {
"musl" => "Alpine Linux (musl)".to_string(),
"glibc" => "Linux (glibc)".to_string(),
"darwin" => "macOS".to_string(),
"windows" => "Windows".to_string(),
_ => "Unknown platform".to_string(),
}
}
pub fn get_current_platform() -> (String, String, String) {
CACHED_PLATFORM
.get_or_init(|| {
let arch = get_current_architecture();
let os = get_current_os();
let lib_c_type = get_foojay_libc_type();
(arch, os, lib_c_type.to_string())
})
.clone()
}
pub fn get_current_architecture() -> String {
#[cfg(target_arch = "x86_64")]
return "x64".to_string();
#[cfg(target_arch = "x86")]
return "x86".to_string();
#[cfg(target_arch = "aarch64")]
return "aarch64".to_string();
#[cfg(target_arch = "arm")]
return "arm32".to_string();
#[cfg(target_arch = "powerpc64")]
{
#[cfg(target_endian = "little")]
return "ppc64le".to_string();
#[cfg(target_endian = "big")]
return "ppc64".to_string();
}
#[cfg(target_arch = "s390x")]
return "s390x".to_string();
#[cfg(not(any(
target_arch = "x86_64",
target_arch = "x86",
target_arch = "aarch64",
target_arch = "arm",
target_arch = "powerpc64",
target_arch = "s390x"
)))]
return "unknown".to_string();
}
pub fn get_current_os() -> String {
#[cfg(target_os = "linux")]
return "linux".to_string();
#[cfg(target_os = "windows")]
return "windows".to_string();
#[cfg(target_os = "macos")]
return "macos".to_string();
#[cfg(not(any(target_os = "linux", target_os = "windows", target_os = "macos")))]
return "unknown".to_string();
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_platform_libc_constant() {
assert!(["musl", "glibc", "darwin", "windows", "unknown"].contains(&PLATFORM_LIBC));
}
#[test]
fn test_get_foojay_libc_type() {
let libc_type = get_foojay_libc_type();
assert!(["musl", "glibc", "libc", "c_std_lib"].contains(&libc_type));
}
#[test]
fn test_matches_foojay_libc_type() {
match PLATFORM_LIBC {
"musl" => {
assert!(matches_foojay_libc_type("musl"));
assert!(!matches_foojay_libc_type("libc"));
}
"glibc" => {
assert!(matches_foojay_libc_type("libc"));
assert!(matches_foojay_libc_type("glibc"));
assert!(!matches_foojay_libc_type("musl"));
}
"darwin" => {
assert!(matches_foojay_libc_type("libc"));
assert!(!matches_foojay_libc_type("musl"));
}
"windows" => {
assert!(matches_foojay_libc_type("c_std_lib"));
assert!(!matches_foojay_libc_type("libc"));
}
_ => {}
}
}
#[test]
fn test_platform_description() {
let description = get_platform_description();
assert!(!description.is_empty());
}
}