tishlang_desktop 1.1.4

cargo:tishlang_desktop / cargo:tishlang_app — cross-device Tish app runtime (Tauri desktop + platform adapters)
//! PlatformHost — thin adapters over native UI hosts (apple / ms / lin / android).

use serde_json::Value;
use tishlang_core::Value as TishValue;

mod android;
mod apple;
mod lin;
mod ms;

#[allow(unused_imports)]
pub use android::AndroidPlatformHost;
#[allow(unused_imports)]
pub use apple::ApplePlatformHost;
#[allow(unused_imports)]
pub use lin::LinPlatformHost;
#[allow(unused_imports)]
pub use ms::MsPlatformHost;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PlatformId {
    Apple,
    Ms,
    Lin,
    Android,
    DesktopTauri,
}

/// Contract for attaching a native surface under the desktop umbrella.
pub trait PlatformHost: Send + Sync {
    fn id(&self) -> PlatformId;
    fn name(&self) -> &'static str;

    /// Whether this host can create `kind: "native"` surfaces in-process.
    fn supports_native_surface(&self) -> bool;

    /// Attach / open a native root without owning the outer event loop.
    /// Default: unsupported.
    fn attach_native(&self, _root: &TishValue, _options: &Value) -> Result<Value, String> {
        Err("native attach unsupported on this platform".into())
    }
}

/// Active host for the current build (apple / ms / lin when feature + OS match).
pub fn current_host() -> Box<dyn PlatformHost> {
    #[cfg(all(feature = "platform-apple", target_os = "macos"))]
    {
        return Box::new(ApplePlatformHost);
    }
    #[cfg(all(feature = "platform-ms", target_os = "windows"))]
    {
        return Box::new(MsPlatformHost);
    }
    #[cfg(all(feature = "platform-lin", target_os = "linux"))]
    {
        return Box::new(LinPlatformHost);
    }
    // Feature enabled off-target (CI): still prefer the named host for attach contracts.
    #[cfg(all(feature = "platform-ms", not(target_os = "windows"), not(all(feature = "platform-apple", target_os = "macos"))))]
    {
        return Box::new(MsPlatformHost);
    }
    #[cfg(all(feature = "platform-lin", not(target_os = "linux"), not(feature = "platform-ms"), not(all(feature = "platform-apple", target_os = "macos"))))]
    {
        return Box::new(LinPlatformHost);
    }
    #[cfg(all(feature = "platform-android", target_os = "android"))]
    {
        return Box::new(AndroidPlatformHost);
    }
    #[cfg(all(
        feature = "platform-android",
        not(target_os = "android"),
        not(feature = "platform-ms"),
        not(feature = "platform-lin"),
        not(all(feature = "platform-apple", target_os = "macos"))
    ))]
    {
        return Box::new(AndroidPlatformHost);
    }
    Box::new(DesktopOnlyHost)
}

struct DesktopOnlyHost;

impl PlatformHost for DesktopOnlyHost {
    fn id(&self) -> PlatformId {
        PlatformId::DesktopTauri
    }

    fn name(&self) -> &'static str {
        "desktop-tauri"
    }

    fn supports_native_surface(&self) -> bool {
        false
    }
}