playwright_rs/protocol/
response.rs1use crate::error::Result;
8use crate::server::channel_owner::{ChannelOwner, ChannelOwnerImpl, ParentOrConnection};
9use serde_json::Value;
10use std::any::Any;
11use std::sync::Arc;
12
13#[derive(Debug, Clone)]
19pub struct HeaderEntry {
20 pub name: String,
22 pub value: String,
24}
25
26#[derive(Clone)]
33pub struct ResponseObject {
34 base: ChannelOwnerImpl,
35}
36
37impl ResponseObject {
38 pub fn new(
43 parent: Arc<dyn ChannelOwner>,
44 type_name: String,
45 guid: Arc<str>,
46 initializer: Value,
47 ) -> Result<Self> {
48 let base = ChannelOwnerImpl::new(
49 ParentOrConnection::Parent(parent),
50 type_name,
51 guid,
52 initializer,
53 );
54
55 Ok(Self { base })
56 }
57
58 pub fn status(&self) -> u16 {
62 self.initializer()
63 .get("status")
64 .and_then(|v| v.as_u64())
65 .unwrap_or(0) as u16
66 }
67
68 pub fn status_text(&self) -> &str {
72 self.initializer()
73 .get("statusText")
74 .and_then(|v| v.as_str())
75 .unwrap_or("")
76 }
77
78 pub fn url(&self) -> &str {
82 self.initializer()
83 .get("url")
84 .and_then(|v| v.as_str())
85 .unwrap_or("")
86 }
87
88 pub async fn body(&self) -> Result<Vec<u8>> {
95 use serde::Deserialize;
96
97 #[derive(Deserialize)]
98 struct BodyResponse {
99 binary: String,
100 }
101
102 let result: BodyResponse = self.channel().send("body", serde_json::json!({})).await?;
103
104 use base64::Engine;
105 let bytes = base64::engine::general_purpose::STANDARD
106 .decode(&result.binary)
107 .map_err(|e| {
108 crate::error::Error::ProtocolError(format!(
109 "Failed to decode response body from base64: {}",
110 e
111 ))
112 })?;
113 Ok(bytes)
114 }
115
116 pub async fn raw_headers(&self) -> Result<Vec<HeaderEntry>> {
122 use serde::Deserialize;
123
124 #[derive(Deserialize)]
125 struct RawHeadersResponse {
126 headers: Vec<HeaderEntryRaw>,
127 }
128
129 #[derive(Deserialize)]
130 struct HeaderEntryRaw {
131 name: String,
132 value: String,
133 }
134
135 let result: RawHeadersResponse = self
136 .channel()
137 .send("rawResponseHeaders", serde_json::json!({}))
138 .await?;
139
140 Ok(result
141 .headers
142 .into_iter()
143 .map(|h| HeaderEntry {
144 name: h.name,
145 value: h.value,
146 })
147 .collect())
148 }
149}
150
151impl ChannelOwner for ResponseObject {
152 fn guid(&self) -> &str {
153 self.base.guid()
154 }
155
156 fn type_name(&self) -> &str {
157 self.base.type_name()
158 }
159
160 fn parent(&self) -> Option<Arc<dyn ChannelOwner>> {
161 self.base.parent()
162 }
163
164 fn connection(&self) -> Arc<dyn crate::server::connection::ConnectionLike> {
165 self.base.connection()
166 }
167
168 fn initializer(&self) -> &Value {
169 self.base.initializer()
170 }
171
172 fn channel(&self) -> &crate::server::channel::Channel {
173 self.base.channel()
174 }
175
176 fn dispose(&self, reason: crate::server::channel_owner::DisposeReason) {
177 self.base.dispose(reason)
178 }
179
180 fn adopt(&self, child: Arc<dyn ChannelOwner>) {
181 self.base.adopt(child)
182 }
183
184 fn add_child(&self, guid: Arc<str>, child: Arc<dyn ChannelOwner>) {
185 self.base.add_child(guid, child)
186 }
187
188 fn remove_child(&self, guid: &str) {
189 self.base.remove_child(guid)
190 }
191
192 fn on_event(&self, _method: &str, _params: Value) {
193 }
195
196 fn was_collected(&self) -> bool {
197 self.base.was_collected()
198 }
199
200 fn as_any(&self) -> &dyn Any {
201 self
202 }
203}
204
205impl std::fmt::Debug for ResponseObject {
206 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207 f.debug_struct("ResponseObject")
208 .field("guid", &self.guid())
209 .finish()
210 }
211}