use std::marker::PhantomData;
use wasm_bindgen::JsCast;
use wasm_bindgen::JsValue;
use wasm_bindgen_futures::JsFuture;
use crate::util::promise_to_void_future;
use super::{sys, IntoStream, ReadableStream};
#[derive(Debug)]
pub struct ReadableStreamDefaultReader<'stream> {
raw: sys::ReadableStreamDefaultReader,
_stream: PhantomData<&'stream mut ReadableStream>,
}
impl<'stream> ReadableStreamDefaultReader<'stream> {
pub(crate) fn new(stream: &mut ReadableStream) -> Result<Self, js_sys::Error> {
Ok(Self {
raw: stream
.as_raw()
.unchecked_ref::<sys::ReadableStreamExt>()
.try_get_reader()?
.unchecked_into(),
_stream: PhantomData,
})
}
#[inline]
pub fn as_raw(&self) -> &sys::ReadableStreamDefaultReader {
&self.raw
}
pub async fn closed(&self) -> Result<(), JsValue> {
promise_to_void_future(self.as_raw().closed()).await
}
pub async fn cancel(&mut self) -> Result<(), JsValue> {
promise_to_void_future(self.as_raw().cancel()).await
}
pub async fn cancel_with_reason(&mut self, reason: &JsValue) -> Result<(), JsValue> {
promise_to_void_future(self.as_raw().cancel_with_reason(reason)).await
}
pub async fn read(&mut self) -> Result<Option<JsValue>, JsValue> {
let promise = self.as_raw().read();
let js_result = JsFuture::from(promise).await?;
let result = sys::ReadableStreamReadResult::from(js_result);
if result.get_done().unwrap_or_default() {
Ok(None)
} else {
Ok(Some(result.get_value()))
}
}
#[inline]
pub fn release_lock(mut self) {
self.release_lock_mut()
}
fn release_lock_mut(&mut self) {
self.as_raw().release_lock()
}
#[inline]
pub fn try_release_lock(self) -> Result<(), (js_sys::Error, Self)> {
self.as_raw()
.unchecked_ref::<sys::ReadableStreamReaderExt>()
.try_release_lock()
.map_err(|err| (err, self))
}
#[inline]
pub fn into_stream(self) -> IntoStream<'stream> {
IntoStream::new(self, false)
}
}
impl Drop for ReadableStreamDefaultReader<'_> {
fn drop(&mut self) {
self.release_lock_mut();
}
}