use crate::error::{Error, Result};
use crate::protocol::{
APIRequestContext, Android, BindingCall, Browser, BrowserContext, BrowserType, CDPSession,
Dialog, Electron, Frame, JSHandle, LocalUtils, Page, Playwright, Request, ResponseObject,
Route, Tracing, WebSocket, Worker, artifact::Artifact,
};
use crate::server::channel_owner::{ChannelOwner, ParentOrConnection};
use crate::server::connection::ConnectionExt;
use serde_json::Value;
use std::sync::Arc;
pub async fn create_object(
parent: ParentOrConnection,
type_name: String,
guid: Arc<str>,
initializer: Value,
) -> Result<Arc<dyn ChannelOwner>> {
let object: Arc<dyn ChannelOwner> = match type_name.as_str() {
"Playwright" => {
let connection = match parent {
ParentOrConnection::Connection(conn) => conn,
ParentOrConnection::Parent(_) => {
return Err(Error::ProtocolError(
"Playwright must have Connection as parent".to_string(),
));
}
};
Arc::new(Playwright::new(connection, type_name, guid, initializer).await?)
}
"BrowserType" => {
Arc::new(BrowserType::new(parent, type_name, guid, initializer)?)
}
"Browser" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Browser must have BrowserType as parent".to_string(),
));
}
};
Arc::new(Browser::new(parent_owner, type_name, guid, initializer)?)
}
"BrowserContext" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"BrowserContext must have Browser as parent".to_string(),
));
}
};
Arc::new(BrowserContext::new(
parent_owner,
type_name,
guid,
initializer,
)?)
}
"Page" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Page must have BrowserContext as parent".to_string(),
));
}
};
Arc::new(Page::new(parent_owner, type_name, guid, initializer)?)
}
"Frame" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Frame must have Page as parent".to_string(),
));
}
};
Arc::new(Frame::new(parent_owner, type_name, guid, initializer)?)
}
"Request" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Request must have a parent object".to_string(),
));
}
};
let request = Arc::new(Request::new(
parent_owner,
type_name,
guid,
initializer.clone(),
)?);
if let Some(frame_guid) = initializer
.get("frame")
.and_then(|v| v.get("guid"))
.and_then(|v| v.as_str())
&& let Ok(frame) = request
.connection()
.get_typed::<crate::protocol::Frame>(frame_guid)
.await
{
request.set_frame(frame);
}
if let Some(from_guid) = initializer
.get("redirectedFrom")
.and_then(|v| v.get("guid"))
.and_then(|v| v.as_str())
&& let Ok(from_request) = request.connection().get_typed::<Request>(from_guid).await
{
request.set_redirected_from(from_request.clone());
from_request.set_redirected_to((*request).clone());
}
request
}
"Route" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Route must have Frame as parent".to_string(),
));
}
};
Arc::new(Route::new(parent_owner, type_name, guid, initializer)?)
}
"Response" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Response must have Request as parent".to_string(),
));
}
};
Arc::new(ResponseObject::new(
parent_owner,
type_name,
guid,
initializer,
)?)
}
"ElementHandle" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"ElementHandle must have Frame as parent".to_string(),
));
}
};
Arc::new(crate::protocol::ElementHandle::new(
parent_owner,
type_name,
guid,
initializer,
)?)
}
"JSHandle" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"JSHandle must have a parent object".to_string(),
));
}
};
Arc::new(JSHandle::new(parent_owner, type_name, guid, initializer)?)
}
"Artifact" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Artifact must have BrowserContext as parent".to_string(),
));
}
};
Arc::new(Artifact::new(parent_owner, type_name, guid, initializer)?)
}
"Dialog" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Dialog must have Page as parent".to_string(),
));
}
};
Arc::new(Dialog::new(parent_owner, type_name, guid, initializer)?)
}
"Android" => {
Arc::new(Android::new(parent, type_name, guid, initializer)?)
}
"Electron" => {
Arc::new(Electron::new(parent, type_name, guid, initializer)?)
}
"CDPSession" => {
Arc::new(CDPSession::new(parent, type_name, guid, initializer)?)
}
"Tracing" => {
Arc::new(Tracing::new(parent, type_name, guid, initializer)?)
}
"APIRequestContext" => {
Arc::new(APIRequestContext::new(
parent,
type_name,
guid,
initializer,
)?)
}
"LocalUtils" => {
Arc::new(LocalUtils::new(parent, type_name, guid, initializer)?)
}
"WebSocket" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"WebSocket must have Page as parent".to_string(),
));
}
};
Arc::new(WebSocket::new(parent_owner, type_name, guid, initializer)?)
}
"BindingCall" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"BindingCall must have a parent object".to_string(),
));
}
};
Arc::new(BindingCall::new(
parent_owner,
type_name,
guid,
initializer,
)?)
}
"Worker" => {
let parent_owner = match parent {
ParentOrConnection::Parent(p) => p,
ParentOrConnection::Connection(_) => {
return Err(Error::ProtocolError(
"Worker must have a parent object".to_string(),
));
}
};
Arc::new(Worker::new(parent_owner, type_name, guid, initializer)?)
}
_ => {
tracing::warn!("Unknown protocol type: {}", type_name);
return Err(Error::ProtocolError(format!(
"Unknown protocol type: {}",
type_name
)));
}
};
Ok(object)
}