ui_automation/
element.rs

1// Copyright (C) 2024 Tristan Gerritsen <tristan@thewoosh.org>
2// All Rights Reserved.
3
4use std::sync::Arc;
5
6use crate::{ClickPosition, ClickRequest, ElementBackend, MouseButton, Position, Rect, Role, Size, UIResult};
7
8#[derive(Debug, Clone)]
9pub struct Element {
10    pub(crate) backend: Arc<dyn ElementBackend>,
11}
12
13impl Element {
14    #[must_use]
15    pub fn children(&self) -> Vec<Element> {
16        self.try_children().unwrap_or_default()
17    }
18
19    pub fn click(&self) {
20        self.try_click().unwrap()
21    }
22
23    #[must_use]
24    pub fn description(&self) -> String {
25        self.try_description().unwrap_or_default()
26    }
27
28    #[must_use]
29    pub fn position(&self) -> Position {
30        self.try_position().unwrap_or_default()
31    }
32
33    #[must_use]
34    pub fn rect(&self) -> Rect {
35        self.try_rect().unwrap_or_default()
36    }
37
38    #[must_use]
39    pub fn size(&self) -> Size {
40        self.try_size().unwrap_or_default()
41    }
42
43    pub fn find<P: FnMut(&Element) -> bool>(&self, mut pred: P) -> Option<Element> {
44        if pred(self) {
45            return Some(self.clone());
46        }
47
48        self.children()
49            .into_iter()
50            .find_map(|element| element.find(&mut pred))
51    }
52
53    #[must_use]
54    pub fn role(&self) -> Role {
55        self.try_role().unwrap_or_default()
56    }
57
58    #[must_use]
59    pub fn url(&self) -> String {
60        self.try_url().unwrap_or_default()
61    }
62
63    #[must_use]
64    pub fn title(&self) -> String {
65        self.try_title().unwrap_or_default()
66    }
67
68    pub fn try_children(&self) -> UIResult<Vec<Element>> {
69        self.backend.children()
70    }
71
72    #[must_use]
73    pub fn try_click(&self) -> UIResult<()> {
74        let request = ClickRequest::new(ClickPosition::Center, MouseButton::Left);
75        self.backend.click(request)
76    }
77
78    pub fn try_description(&self) -> UIResult<String> {
79        self.backend.description()
80    }
81
82    #[must_use]
83    pub fn try_position(&self) -> UIResult<Position> {
84        self.backend.position()
85    }
86
87    #[must_use]
88    pub fn try_rect(&self) -> UIResult<Rect> {
89        self.backend.rect()
90    }
91
92    #[must_use]
93    pub fn try_size(&self) -> UIResult<Size> {
94        self.backend.size()
95    }
96
97    pub fn try_role(&self) -> UIResult<Role> {
98        self.backend.role()
99    }
100
101    pub fn try_title(&self) -> UIResult<String> {
102        self.backend.title()
103    }
104
105    #[must_use]
106    pub fn try_url(&self) -> UIResult<String> {
107        self.backend.url()
108    }
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub(crate) struct ElementId(pub usize);