ntwrk/logic/browser/tools/
element.rs

1use super::behaviors::{ElementRead, ElementWrite};
2use crate::{
3    logic::browser::drivers::behaviors::{DriverRead, DriverWrite},
4    types::{error::Error, result::Result, wsstream::WSStream},
5};
6use futures::{SinkExt, StreamExt};
7use serde::{de::DeserializeOwned, Deserialize, Serialize};
8use std::sync::Arc;
9use tokio::sync::RwLock;
10use tokio_tungstenite::tungstenite::Message;
11
12#[derive(Serialize, Deserialize, Debug, Clone)]
13pub struct Element<D: DriverRead + DriverWrite> {
14    #[serde(skip)]
15    pub(crate) parent: Option<Arc<RwLock<WSStream>>>,
16    #[serde(skip)]
17    pub(crate) state: std::marker::PhantomData<D>,
18    pub(crate) object_id: String,
19}
20impl<D: DriverRead + DriverWrite> ElementRead<D> for Element<D> {
21    async fn get_text(&self) -> Result<serde_json::Value> {
22        self.send_command(D::get_text(&self.object_id)).await
23    }
24    async fn send_command<T>(&self, command: serde_json::Value) -> Result<T>
25    where
26        T: DeserializeOwned,
27    {
28        let mut stream = match self.parent.as_ref() {
29            Some(stream) => stream.write().await,
30            None => return Err(Error::Custom("Could not send command".into())),
31        };
32
33        stream.0.send(Message::Text(command.to_string())).await?;
34
35        while let Some(msg) = stream.1.next().await {
36            match msg {
37                Ok(Message::Text(text)) => {
38                    println!("Received msg: \n{text}");
39                    match serde_json::from_str::<T>(&text) {
40                        Ok(response) => return Ok(response),
41                        Err(_) => eprintln!("Can't deserialize:\n{text}\n"),
42                    }
43                }
44                Ok(_) => continue,
45                Err(_) => eprintln!("Can't deserialize:\n{:?}\n", msg),
46            }
47        }
48        Err(Error::Custom("Could not send command".into()))
49    }
50}
51impl<D: DriverRead + DriverWrite> ElementWrite<D> for Element<D> {
52    async fn click(&self) -> Result<serde_json::Value> {
53        self.send_command(D::click_element(&self.object_id)).await
54    }
55    async fn focus(&self) -> Result<serde_json::Value> {
56        self.send_command(D::focus(&self.object_id)).await
57    }
58    async fn set_text(&self, text: &str) -> Result<serde_json::Value> {
59        _ = self.focus().await;
60        self.send_command(D::set_text(text)).await
61    }
62}