playwright/imp/
js_handle.rs

1use crate::imp::{core::*, prelude::*};
2use std::fmt;
3
4#[derive(Debug)]
5pub(crate) struct JsHandle {
6    channel: ChannelOwner,
7    var: Mutex<Var>
8}
9
10#[derive(Debug)]
11struct Var {
12    preview: String
13}
14
15impl JsHandle {
16    pub(crate) fn try_new(channel: ChannelOwner) -> Result<Self, Error> {
17        let Initializer { preview } = serde_json::from_value(channel.initializer.clone())?;
18        let var = Mutex::new(Var { preview });
19        Ok(Self { channel, var })
20    }
21
22    pub(crate) async fn get_property(&self, name: &str) -> ArcResult<Weak<JsHandle>> {
23        let mut args = HashMap::new();
24        args.insert("name", name);
25        let v = send_message!(self, "getProperty", args);
26        let guid = only_guid(&v)?;
27        let j = get_object!(self.context()?.lock().unwrap(), guid, JsHandle)?;
28        Ok(j)
29    }
30
31    pub(crate) async fn get_properties(&self) -> ArcResult<HashMap<String, Weak<JsHandle>>> {
32        let v = send_message!(self, "getPropertyList", Map::new());
33        let first = first(&v).ok_or(Error::InvalidParams)?;
34        let properties: Vec<Property> =
35            serde_json::from_value((*first).clone()).map_err(Error::Serde)?;
36        let ps = properties
37            .into_iter()
38            .map(
39                |Property {
40                     name,
41                     value: OnlyGuid { guid }
42                 }| {
43                    get_object!(self.context()?.lock().unwrap(), &guid, JsHandle).map(|o| (name, o))
44                }
45            )
46            .collect::<Result<HashMap<_, _>, Error>>()?;
47        Ok(ps)
48    }
49
50    pub(crate) async fn dispose(&self) -> ArcResult<()> {
51        let _ = send_message!(self, "dispose", Map::new());
52        Ok(())
53    }
54
55    pub(crate) async fn json_value<U>(&self) -> ArcResult<U>
56    where
57        U: DeserializeOwned
58    {
59        let v = send_message!(self, "jsonValue", Map::new());
60        let first = first(&v).ok_or(Error::ObjectNotFound)?;
61        Ok(de::from_value(first).map_err(Error::DeserializationPwJson)?)
62    }
63}
64
65impl JsHandle {
66    fn set_preview(&self, preview: String) {
67        let var = &mut self.var.lock().unwrap();
68        var.preview = preview;
69    }
70
71    fn on_preview_updated(&self, params: Map<String, Value>) -> Result<(), Error> {
72        #[derive(Deserialize)]
73        struct De {
74            preview: String
75        }
76        let De { preview } = serde_json::from_value(params.into())?;
77        self.set_preview(preview);
78        Ok(())
79    }
80}
81
82impl RemoteObject for JsHandle {
83    fn channel(&self) -> &ChannelOwner { &self.channel }
84    fn channel_mut(&mut self) -> &mut ChannelOwner { &mut self.channel }
85
86    fn handle_event(
87        &self,
88        _ctx: &Context,
89        method: Str<Method>,
90        params: Map<String, Value>
91    ) -> Result<(), Error> {
92        if method.as_str() == "previewUpdated" {
93            self.on_preview_updated(params)?;
94        }
95        Ok(())
96    }
97}
98
99impl fmt::Display for JsHandle {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        write!(f, "{}", &self.var.lock().unwrap().preview)
102    }
103}
104
105#[derive(Debug, Deserialize)]
106#[serde(rename_all = "camelCase")]
107struct Initializer {
108    preview: String
109}
110
111#[derive(Deserialize)]
112struct Property {
113    name: String,
114    value: OnlyGuid
115}