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::sync::Arc;

use crate::{ClickPosition, ClickRequest, ElementBackend, MouseButton, Position, Rect, Role, Size, UIResult};

#[derive(Debug, Clone)]
pub struct Element {
    pub(crate) backend: Arc<dyn ElementBackend>,
}

impl Element {
    #[must_use]
    pub fn children(&self) -> Vec<Element> {
        self.try_children().unwrap_or_default()
    }

    pub fn click(&self) {
        self.try_click().unwrap()
    }

    #[must_use]
    pub fn description(&self) -> String {
        self.try_description().unwrap_or_default()
    }

    #[must_use]
    pub fn position(&self) -> Position {
        self.try_position().unwrap_or_default()
    }

    #[must_use]
    pub fn rect(&self) -> Rect {
        self.try_rect().unwrap_or_default()
    }

    #[must_use]
    pub fn size(&self) -> Size {
        self.try_size().unwrap_or_default()
    }

    pub fn find<P: FnMut(&Element) -> bool>(&self, mut pred: P) -> Option<Element> {
        if pred(self) {
            return Some(self.clone());
        }

        self.children()
            .into_iter()
            .find_map(|element| element.find(&mut pred))
    }

    #[must_use]
    pub fn role(&self) -> Role {
        self.try_role().unwrap_or_default()
    }

    #[must_use]
    pub fn url(&self) -> String {
        self.try_url().unwrap_or_default()
    }

    #[must_use]
    pub fn title(&self) -> String {
        self.try_title().unwrap_or_default()
    }

    pub fn try_children(&self) -> UIResult<Vec<Element>> {
        self.backend.children()
    }

    #[must_use]
    pub fn try_click(&self) -> UIResult<()> {
        let request = ClickRequest::new(ClickPosition::Center, MouseButton::Left);
        self.backend.click(request)
    }

    pub fn try_description(&self) -> UIResult<String> {
        self.backend.description()
    }

    #[must_use]
    pub fn try_position(&self) -> UIResult<Position> {
        self.backend.position()
    }

    #[must_use]
    pub fn try_rect(&self) -> UIResult<Rect> {
        self.backend.rect()
    }

    #[must_use]
    pub fn try_size(&self) -> UIResult<Size> {
        self.backend.size()
    }

    pub fn try_role(&self) -> UIResult<Role> {
        self.backend.role()
    }

    pub fn try_title(&self) -> UIResult<String> {
        self.backend.title()
    }

    #[must_use]
    pub fn try_url(&self) -> UIResult<String> {
        self.backend.url()
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct ElementId(pub usize);