use std::sync::Arc;
use serde_json::Value;
use super::BidiEvent;
use super::capabilities::resolve_bidi_websocket_url;
use super::command::BidiCommand;
use super::error::BidiError;
use super::modules;
use super::stream::{EventStream, RawEventStream};
use super::transport::ws::BidiTransport;
use crate::error::WebDriverResult;
use crate::session::handle::SessionHandle;
#[derive(Debug, Clone)]
pub struct BiDi {
transport: BidiTransport,
}
impl BiDi {
pub(crate) async fn connect(handle: Arc<SessionHandle>) -> WebDriverResult<Self> {
let url = resolve_bidi_websocket_url(&handle)?;
let transport = BidiTransport::connect(&url).await?;
Ok(Self {
transport,
})
}
pub async fn send<C: BidiCommand>(&self, params: C) -> Result<C::Returns, BidiError> {
let raw = self
.transport
.send_raw(C::METHOD, serde_json::to_value(params).map_err(serde_err)?)
.await?;
serde_json::from_value(raw).map_err(serde_err)
}
pub async fn send_raw<P: serde::Serialize>(
&self,
method: &str,
params: P,
) -> Result<Value, BidiError> {
let value = serde_json::to_value(params).map_err(serde_err)?;
self.transport.send_raw(method, value).await
}
pub async fn subscribe<E: BidiEvent>(&self) -> Result<EventStream<E>, BidiError> {
self.transport.ensure_subscribed(E::METHOD).await?;
Ok(EventStream::new(self.transport.clone(), self.transport.subscribe_events(), E::METHOD))
}
pub fn subscribe_raw(&self) -> RawEventStream {
RawEventStream::new(self.transport.subscribe_events())
}
pub fn session(&self) -> modules::session::SessionModule<'_> {
modules::session::SessionModule::new(self)
}
pub fn browser(&self) -> modules::browser::BrowserModule<'_> {
modules::browser::BrowserModule::new(self)
}
pub fn browsing_context(&self) -> modules::browsing_context::BrowsingContextModule<'_> {
modules::browsing_context::BrowsingContextModule::new(self)
}
pub fn script(&self) -> modules::script::ScriptModule<'_> {
modules::script::ScriptModule::new(self)
}
pub fn network(&self) -> modules::network::NetworkModule<'_> {
modules::network::NetworkModule::new(self)
}
pub fn storage(&self) -> modules::storage::StorageModule<'_> {
modules::storage::StorageModule::new(self)
}
pub fn log(&self) -> modules::log::LogModule<'_> {
modules::log::LogModule::new(self)
}
pub fn input(&self) -> modules::input::InputModule<'_> {
modules::input::InputModule::new(self)
}
pub fn permissions(&self) -> modules::permissions::PermissionsModule<'_> {
modules::permissions::PermissionsModule::new(self)
}
pub fn emulation(&self) -> modules::emulation::EmulationModule<'_> {
modules::emulation::EmulationModule::new(self)
}
pub fn web_extension(&self) -> modules::web_extension::WebExtensionModule<'_> {
modules::web_extension::WebExtensionModule::new(self)
}
}
fn serde_err(e: serde_json::Error) -> BidiError {
BidiError {
command: "<serde>".to_string(),
error: "unknown error".to_string(),
message: e.to_string(),
stacktrace: None,
}
}