zsui 0.3.0-alpha.2

Rust-first feature-gated native UI framework for Win32, AppKit, and Linux.
Documentation
#[cfg(all(windows, feature = "windows-gdi"))]
pub(super) fn capture_windows(
    sample_point: &'static str,
) -> Option<crate::NativeProofProcessMemoryEvidence> {
    use windows_sys::Win32::System::{
        ProcessStatus::{
            GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS, PROCESS_MEMORY_COUNTERS_EX,
        },
        Threading::GetCurrentProcess,
    };

    let mut counters = unsafe { std::mem::zeroed::<PROCESS_MEMORY_COUNTERS_EX>() };
    counters.cb = std::mem::size_of::<PROCESS_MEMORY_COUNTERS_EX>() as u32;
    let captured = unsafe {
        GetProcessMemoryInfo(
            GetCurrentProcess(),
            (&mut counters as *mut PROCESS_MEMORY_COUNTERS_EX).cast::<PROCESS_MEMORY_COUNTERS>(),
            counters.cb,
        )
    };
    (captured != 0).then(|| crate::NativeProofProcessMemoryEvidence {
        source: "win32_get_process_memory_info",
        sample_point,
        resident_bytes: counters.WorkingSetSize as u64,
        peak_resident_bytes: counters.PeakWorkingSetSize as u64,
        private_bytes: Some(counters.PrivateUsage as u64),
        peak_private_bytes: Some(counters.PeakPagefileUsage as u64),
        proportional_set_size_bytes: None,
        virtual_bytes: None,
    })
}

#[cfg(all(target_os = "macos", feature = "macos-appkit"))]
#[allow(deprecated)]
pub(super) fn capture_macos(
    sample_point: &'static str,
) -> Option<crate::NativeProofProcessMemoryEvidence> {
    let mut info = unsafe { std::mem::zeroed::<libc::mach_task_basic_info>() };
    let mut count = libc::MACH_TASK_BASIC_INFO_COUNT;
    let captured = unsafe {
        libc::task_info(
            libc::mach_task_self(),
            libc::MACH_TASK_BASIC_INFO as libc::task_flavor_t,
            (&mut info as *mut libc::mach_task_basic_info).cast::<libc::integer_t>(),
            &mut count,
        )
    };
    if captured != libc::KERN_SUCCESS {
        return None;
    }
    let resident_bytes = unsafe { std::ptr::addr_of!(info.resident_size).read_unaligned() };
    let peak_resident_bytes =
        unsafe { std::ptr::addr_of!(info.resident_size_max).read_unaligned() };
    let virtual_bytes = unsafe { std::ptr::addr_of!(info.virtual_size).read_unaligned() };
    Some(crate::NativeProofProcessMemoryEvidence {
        source: "macos_mach_task_basic_info",
        sample_point,
        resident_bytes,
        peak_resident_bytes: peak_resident_bytes.max(resident_bytes),
        private_bytes: None,
        peak_private_bytes: None,
        proportional_set_size_bytes: None,
        virtual_bytes: Some(virtual_bytes),
    })
}

#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
pub(super) fn capture_linux(
    sample_point: &'static str,
) -> Option<crate::NativeProofProcessMemoryEvidence> {
    let status = std::fs::read_to_string("/proc/self/status").ok()?;
    let resident_bytes = linux_proc_kib(&status, "VmRSS:")?;
    let peak_resident_bytes = linux_proc_kib(&status, "VmHWM:").unwrap_or(resident_bytes);
    let virtual_bytes = linux_proc_kib(&status, "VmSize:");
    let rollup = std::fs::read_to_string("/proc/self/smaps_rollup").ok();
    let private_bytes = rollup.as_deref().map(|rollup| {
        ["Private_Clean:", "Private_Dirty:", "Private_Hugetlb:"]
            .into_iter()
            .filter_map(|key| linux_proc_kib(rollup, key))
            .sum::<u64>()
    });
    let proportional_set_size_bytes = rollup
        .as_deref()
        .and_then(|rollup| linux_proc_kib(rollup, "Pss:"));
    Some(crate::NativeProofProcessMemoryEvidence {
        source: "linux_procfs_status_smaps_rollup",
        sample_point,
        resident_bytes,
        peak_resident_bytes: peak_resident_bytes.max(resident_bytes),
        private_bytes,
        peak_private_bytes: None,
        proportional_set_size_bytes,
        virtual_bytes,
    })
}

#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
fn linux_proc_kib(contents: &str, key: &str) -> Option<u64> {
    let line = contents.lines().find(|line| line.starts_with(key))?;
    let kib = line[key.len()..]
        .split_whitespace()
        .next()?
        .parse::<u64>()
        .ok()?;
    kib.checked_mul(1_024)
}