automata_windows/
locator.rs1use super::{Selector, UIElement, UiError};
2
3pub struct Locator {
5 root: UIElement,
6 selector: Selector,
7}
8
9impl Locator {
10 #[cfg_attr(not(target_os = "windows"), allow(dead_code))]
11 pub(crate) fn new(root: UIElement, selector: Selector) -> Self {
12 Self { root, selector }
13 }
14
15 pub fn find(&self) -> Result<UIElement, UiError> {
18 find_in(&self.root, &self.selector)
19 }
20}
21
22fn matches(el: &UIElement, selector: &Selector) -> bool {
23 match selector {
24 Selector::Role { role, name } => {
25 if el.role() != *role {
26 return false;
27 }
28 match name {
29 None => true,
30 Some(n) => el.name_or_empty() == *n,
31 }
32 }
33 }
34}
35
36fn find_in(el: &UIElement, selector: &Selector) -> Result<UIElement, UiError> {
37 let children = el
38 .children()
39 .map_err(|e| UiError::Platform(e.to_string()))?;
40 for child in children {
41 if matches(&child, selector) {
42 return Ok(child);
43 }
44 if let Ok(found) = find_in(&child, selector) {
45 return Ok(found);
46 }
47 }
48 Err(UiError::Internal(format!(
49 "Element not found: {selector:?}"
50 )))
51}