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