playwright_rs/protocol/
worker.rs1use crate::error::Result;
4use crate::protocol::evaluate_conversion::{parse_result, serialize_argument, serialize_null};
5use crate::server::channel::Channel;
6use crate::server::channel_owner::{ChannelOwner, ChannelOwnerImpl, ParentOrConnection};
7use serde::de::DeserializeOwned;
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10use std::any::Any;
11use std::sync::Arc;
12
13#[derive(Clone)]
41pub struct Worker {
42 base: ChannelOwnerImpl,
43 url: String,
45}
46
47impl Worker {
48 pub fn new(
53 parent: Arc<dyn ChannelOwner>,
54 type_name: String,
55 guid: Arc<str>,
56 initializer: Value,
57 ) -> Result<Self> {
58 let url = initializer
59 .get("url")
60 .and_then(|v| v.as_str())
61 .unwrap_or("")
62 .to_string();
63
64 let base = ChannelOwnerImpl::new(
65 ParentOrConnection::Parent(parent),
66 type_name,
67 guid,
68 initializer,
69 );
70
71 Ok(Self { base, url })
72 }
73
74 pub fn url(&self) -> &str {
78 &self.url
79 }
80
81 fn channel(&self) -> &Channel {
83 self.base.channel()
84 }
85
86 #[tracing::instrument(level = "debug", skip_all, fields(guid = %self.guid()))]
102 pub async fn evaluate<R, T>(&self, expression: &str, arg: Option<T>) -> Result<R>
103 where
104 R: DeserializeOwned,
105 T: Serialize,
106 {
107 let serialized_arg = match arg {
108 Some(a) => serialize_argument(&a),
109 None => serialize_null(),
110 };
111
112 let params = serde_json::json!({
113 "expression": expression,
114 "arg": serialized_arg
115 });
116
117 #[derive(Deserialize)]
118 struct EvaluateResult {
119 value: Value,
120 }
121
122 let result: EvaluateResult = self.channel().send("evaluateExpression", params).await?;
123 let parsed = parse_result(&result.value);
124
125 serde_json::from_value(parsed).map_err(|e| {
126 crate::error::Error::ProtocolError(format!("Failed to deserialize result: {}", e))
127 })
128 }
129
130 #[tracing::instrument(level = "debug", skip_all, fields(guid = %self.guid()))]
141 pub async fn evaluate_handle(
142 &self,
143 expression: &str,
144 ) -> Result<Arc<crate::protocol::JSHandle>> {
145 let params = serde_json::json!({
148 "expression": expression,
149 "arg": {"value": {"v": "undefined"}, "handles": []}
150 });
151
152 #[derive(Deserialize)]
153 struct HandleRef {
154 guid: String,
155 }
156 #[derive(Deserialize)]
157 struct EvaluateHandleResponse {
158 handle: HandleRef,
159 }
160
161 let response: EvaluateHandleResponse = self
162 .channel()
163 .send("evaluateExpressionHandle", params)
164 .await?;
165
166 let guid = &response.handle.guid;
167 let handle = crate::protocol::JSHandle::wait_for(&self.base.connection(), guid).await?;
168
169 Ok(Arc::new(handle))
170 }
171}
172
173impl ChannelOwner for Worker {
174 fn guid(&self) -> &str {
175 self.base.guid()
176 }
177
178 fn type_name(&self) -> &str {
179 self.base.type_name()
180 }
181
182 fn parent(&self) -> Option<Arc<dyn ChannelOwner>> {
183 self.base.parent()
184 }
185
186 fn connection(&self) -> Arc<dyn crate::server::connection::ConnectionLike> {
187 self.base.connection()
188 }
189
190 fn initializer(&self) -> &Value {
191 self.base.initializer()
192 }
193
194 fn channel(&self) -> &Channel {
195 self.base.channel()
196 }
197
198 fn dispose(&self, reason: crate::server::channel_owner::DisposeReason) {
199 self.base.dispose(reason)
200 }
201
202 fn adopt(&self, child: Arc<dyn ChannelOwner>) {
203 self.base.adopt(child)
204 }
205
206 fn add_child(&self, guid: Arc<str>, child: Arc<dyn ChannelOwner>) {
207 self.base.add_child(guid, child)
208 }
209
210 fn remove_child(&self, guid: &str) {
211 self.base.remove_child(guid)
212 }
213
214 fn on_event(&self, _method: &str, _params: Value) {
215 }
217
218 fn was_collected(&self) -> bool {
219 self.base.was_collected()
220 }
221
222 fn as_any(&self) -> &dyn Any {
223 self
224 }
225}
226
227impl std::fmt::Debug for Worker {
228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229 f.debug_struct("Worker")
230 .field("guid", &self.guid())
231 .field("url", &self.url)
232 .finish()
233 }
234}