use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum HostClass {
Mobile,
Desktop,
}
impl HostClass {
pub const fn as_str(self) -> &'static str {
match self {
Self::Mobile => "mobile",
Self::Desktop => "desktop",
}
}
const fn built_for() -> Self {
if cfg!(any(
target_os = "ios",
target_os = "android",
target_env = "ohos"
)) {
Self::Mobile
} else {
Self::Desktop
}
}
}
const UNSET: u8 = 0;
const MOBILE: u8 = 1;
const DESKTOP: u8 = 2;
static OVERRIDE: AtomicU8 = AtomicU8::new(UNSET);
static PAD: AtomicBool = AtomicBool::new(false);
pub fn host_class() -> HostClass {
match OVERRIDE.load(Ordering::Relaxed) {
MOBILE => HostClass::Mobile,
DESKTOP => HostClass::Desktop,
_ => HostClass::built_for(),
}
}
pub fn set_host_class(class: HostClass) {
let changed = host_class() != class;
OVERRIDE.store(
match class {
HostClass::Mobile => MOBILE,
HostClass::Desktop => DESKTOP,
},
Ordering::Relaxed,
);
if changed {
super::runtime_registry::reload_pages_for_host_class_change();
}
}
pub fn is_pad() -> bool {
PAD.load(Ordering::Relaxed)
}
pub fn set_pad(pad: bool) {
PAD.store(pad, Ordering::Relaxed);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn override_replaces_the_build_target_both_ways() {
set_host_class(HostClass::Mobile);
assert_eq!(host_class(), HostClass::Mobile);
set_host_class(HostClass::Desktop);
assert_eq!(host_class(), HostClass::Desktop);
assert_eq!(HostClass::Mobile.as_str(), "mobile");
assert_eq!(HostClass::Desktop.as_str(), "desktop");
OVERRIDE.store(UNSET, Ordering::Relaxed);
PAD.store(false, Ordering::Relaxed);
assert_eq!(host_class(), HostClass::built_for());
assert!(!is_pad());
}
#[test]
fn pad_is_orthogonal_to_host_class() {
set_host_class(HostClass::Mobile);
set_pad(true);
assert_eq!(host_class(), HostClass::Mobile);
assert!(is_pad());
set_pad(false);
assert_eq!(host_class(), HostClass::Mobile);
assert!(!is_pad());
OVERRIDE.store(UNSET, Ordering::Relaxed);
}
}