playwright 0.0.20

Playwright port to Rust
Documentation
use crate::imp::{core::*, prelude::*};
use std::fmt;

#[derive(Debug)]
pub(crate) struct JsHandle {
    channel: ChannelOwner,
    var: Mutex<Var>
}

#[derive(Debug)]
struct Var {
    preview: String
}

impl JsHandle {
    pub(crate) fn try_new(channel: ChannelOwner) -> Result<Self, Error> {
        let Initializer { preview } = serde_json::from_value(channel.initializer.clone())?;
        let var = Mutex::new(Var { preview });
        Ok(Self { channel, var })
    }

    pub(crate) async fn get_property(&self, name: &str) -> ArcResult<Weak<JsHandle>> {
        let mut args = HashMap::new();
        args.insert("name", name);
        let v = send_message!(self, "getProperty", args);
        let guid = only_guid(&v)?;
        let j = get_object!(self.context()?.lock().unwrap(), guid, JsHandle)?;
        Ok(j)
    }

    pub(crate) async fn get_properties(&self) -> ArcResult<HashMap<String, Weak<JsHandle>>> {
        let v = send_message!(self, "getPropertyList", Map::new());
        let first = first(&v).ok_or(Error::InvalidParams)?;
        let properties: Vec<Property> =
            serde_json::from_value((*first).clone()).map_err(Error::Serde)?;
        let ps = properties
            .into_iter()
            .map(
                |Property {
                     name,
                     value: OnlyGuid { guid }
                 }| {
                    get_object!(self.context()?.lock().unwrap(), &guid, JsHandle).map(|o| (name, o))
                }
            )
            .collect::<Result<HashMap<_, _>, Error>>()?;
        Ok(ps)
    }

    pub(crate) async fn dispose(&self) -> ArcResult<()> {
        let _ = send_message!(self, "dispose", Map::new());
        Ok(())
    }

    pub(crate) async fn json_value<U>(&self) -> ArcResult<U>
    where
        U: DeserializeOwned
    {
        let v = send_message!(self, "jsonValue", Map::new());
        let first = first(&v).ok_or(Error::ObjectNotFound)?;
        Ok(de::from_value(first).map_err(Error::DeserializationPwJson)?)
    }
}

impl JsHandle {
    fn set_preview(&self, preview: String) {
        let var = &mut self.var.lock().unwrap();
        var.preview = preview;
    }

    fn on_preview_updated(&self, params: Map<String, Value>) -> Result<(), Error> {
        #[derive(Deserialize)]
        struct De {
            preview: String
        }
        let De { preview } = serde_json::from_value(params.into())?;
        self.set_preview(preview);
        Ok(())
    }
}

impl RemoteObject for JsHandle {
    fn channel(&self) -> &ChannelOwner { &self.channel }
    fn channel_mut(&mut self) -> &mut ChannelOwner { &mut self.channel }

    fn handle_event(
        &self,
        _ctx: &Context,
        method: Str<Method>,
        params: Map<String, Value>
    ) -> Result<(), Error> {
        if method.as_str() == "previewUpdated" {
            self.on_preview_updated(params)?;
        }
        Ok(())
    }
}

impl fmt::Display for JsHandle {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", &self.var.lock().unwrap().preview)
    }
}

#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct Initializer {
    preview: String
}

#[derive(Deserialize)]
struct Property {
    name: String,
    value: OnlyGuid
}