kael 0.2.0

GPU-accelerated native UI framework for Rust — build desktop apps with Metal, DirectX, and Vulkan rendering
Documentation
use crate::NetworkStatus;
use std::ffi::c_void;

#[link(name = "SystemConfiguration", kind = "framework")]
unsafe extern "C" {
    fn SCNetworkReachabilityCreateWithName(
        allocator: *const c_void,
        nodename: *const u8,
    ) -> *const c_void;
    fn SCNetworkReachabilityGetFlags(target: *const c_void, flags: *mut u32) -> u8;
}

#[link(name = "Network", kind = "framework")]
unsafe extern "C" {
    fn nw_path_monitor_create() -> *const c_void;
    fn nw_path_monitor_set_update_handler(monitor: *const c_void, handler: *const c_void);
    fn nw_path_monitor_set_queue(monitor: *const c_void, queue: *const c_void);
    fn nw_path_monitor_start(monitor: *const c_void);
    fn nw_path_monitor_cancel(monitor: *const c_void);
    fn nw_path_get_status(path: *const c_void) -> i32;
}

const K_SC_NETWORK_REACHABILITY_FLAGS_REACHABLE: u32 = 1 << 1;
const NW_PATH_STATUS_SATISFIED: i32 = 1;

pub(crate) fn network_status() -> NetworkStatus {
    unsafe {
        let host = b"captive.apple.com\0";
        let reachability = SCNetworkReachabilityCreateWithName(std::ptr::null(), host.as_ptr());
        if reachability.is_null() {
            return NetworkStatus::Offline;
        }

        let mut flags: u32 = 0;
        let ok = SCNetworkReachabilityGetFlags(reachability, &mut flags);

        core_foundation::base::CFRelease(reachability as core_foundation::base::CFTypeRef);

        if ok != 0 && (flags & K_SC_NETWORK_REACHABILITY_FLAGS_REACHABLE) != 0 {
            NetworkStatus::Online
        } else {
            NetworkStatus::Offline
        }
    }
}

pub(crate) fn path_status_to_network_status(path: *const c_void) -> NetworkStatus {
    let status = unsafe { nw_path_get_status(path) };
    if status == NW_PATH_STATUS_SATISFIED {
        NetworkStatus::Online
    } else {
        NetworkStatus::Offline
    }
}

pub(crate) unsafe fn create_path_monitor() -> *const c_void {
    unsafe { nw_path_monitor_create() }
}

pub(crate) unsafe fn start_path_monitor(
    monitor: *const c_void,
    handler_block: *const c_void,
    queue: *const c_void,
) {
    unsafe {
        nw_path_monitor_set_update_handler(monitor, handler_block);
        nw_path_monitor_set_queue(monitor, queue);
        nw_path_monitor_start(monitor);
    }
}

pub(crate) unsafe fn cancel_path_monitor(monitor: *const c_void) {
    if !monitor.is_null() {
        unsafe {
            nw_path_monitor_cancel(monitor);
        }
    }
}