use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ScreenBounds {
pub x: i64,
pub y: i64,
pub width: i64,
pub height: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WidgetNode {
pub id: String,
pub role: String,
pub name: Option<String>,
pub value: Option<String>,
pub bounds: Option<ScreenBounds>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub children: Vec<WidgetNode>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OcrTextItem {
pub text: String,
pub bounds: ScreenBounds,
pub confidence: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScreenState {
pub screenshot_path: Option<String>,
pub widget_tree: Option<WidgetNode>,
pub extracted_text: Vec<OcrTextItem>,
}
#[async_trait]
pub trait PerceptionProvider: Send + Sync {
fn name(&self) -> &str;
async fn capture_state(&self) -> anyhow::Result<ScreenState>;
}