ui-automation 0.1.1

Control the User Interface, cross-platform.
Documentation
// Copyright (C) 2024 Tristan Gerritsen <tristan@thewoosh.org>
// All Rights Reserved.

use std::ffi::c_void;

use crate::backend::macos::{
    core_foundation::{CFType, CFTypeRef},
    core_graphics::{CGPoint, CGRect, CGSize},
};

pub type AXValueRef = CFTypeRef;

pub struct AXValue {
    inner: CFType,
}

impl AXValue {
    pub fn from_get(inner: CFType) -> Self {
        Self { inner }
    }

    pub fn get(&self) -> AXValueKind {
        match self.get_type() {
            AXValueType::CGPoint => {
                let mut pt = CGPoint::default();
                let result = unsafe { AXValueGetValue(self.inner.ptr(), 1, &mut pt as *mut CGPoint as *mut c_void) };
                debug_assert!(result);
                AXValueKind::CGPoint(pt)
            },
            AXValueType::CGSize => {
                let mut size = CGSize::default();
                let result = unsafe { AXValueGetValue(self.inner.ptr(), 2, &mut size as *mut CGSize as *mut c_void) };
                debug_assert!(result);
                AXValueKind::CGSize(size)
            },
            AXValueType::CGRect => {
                let mut size = CGRect::default();
                let result = unsafe { AXValueGetValue(self.inner.ptr(), 3, &mut size as *mut CGRect as *mut c_void) };
                debug_assert!(result);
                AXValueKind::CGRect(size)
            },
            ty => AXValueKind::Unknown(ty),
        }
    }

    #[must_use]
    pub fn get_type(&self) -> AXValueType {
        unsafe { AXValueGetType(self.inner.ptr()) }.into()
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AXValueType {
    Illegal,
    CGPoint,
    CGSize,
    CGRect,
    CGRange,
    AXError,
    Unknown(u32),
}

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum AXValueKind {
    Unknown(AXValueType),
    CGPoint(CGPoint),
    CGSize(CGSize),
    CGRect(CGRect),
}

impl From<u32> for AXValueType {
    fn from(value: u32) -> Self {
        match value {
            0 => Self::Illegal,
            1 => Self::CGPoint,
            2 => Self::CGSize,
            3 => Self::CGRect,
            4 => Self::CGRange,
            5 => Self::AXError,
            val => Self::Unknown(val),
        }
    }
}

extern "C-unwind" {
    fn AXValueGetType(value: AXValueRef) -> u32;
    fn AXValueGetValue(value: AXValueRef, ty: u32, ptr: *mut c_void) -> bool;
}