use bytes::Bytes;
pub struct JsBody(Option<web_sys::ReadableStream>);
impl JsBody {
pub fn new(stream: Option<web_sys::ReadableStream>) -> Self {
Self(stream)
}
pub fn stream(&self) -> Option<&web_sys::ReadableStream> {
self.0.as_ref()
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
if bytes.is_empty() {
return Ok(Self::new(None));
}
let mut buf = bytes.to_vec();
let resp = web_sys::Response::new_with_opt_u8_array(Some(&mut buf))
.map_err(|e| format!("Response::new failed: {:?}", e))?;
Ok(Self::new(resp.body()))
}
}
unsafe impl Send for JsBody {}
unsafe impl Sync for JsBody {}
pub async fn collect_js_body(body: JsBody) -> std::result::Result<Bytes, String> {
match body.0 {
None => Ok(Bytes::new()),
Some(stream) => {
let resp = web_sys::Response::new_with_opt_readable_stream(Some(&stream))
.map_err(|e| format!("Response::new failed: {:?}", e))?;
let promise = resp
.array_buffer()
.map_err(|e| format!("arrayBuffer() failed: {:?}", e))?;
let buf = wasm_bindgen_futures::JsFuture::from(promise)
.await
.map_err(|e| format!("arrayBuffer await failed: {:?}", e))?;
let uint8 = js_sys::Uint8Array::new(&buf);
Ok(Bytes::from(uint8.to_vec()))
}
}
}