1use 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);