use bytes::Buf;
use js_sys::{Reflect, Uint8Array};
use web_sys::WebTransportSendStream;
use crate::Error;
use web_streams::Writer;
pub struct SendStream {
stream: WebTransportSendStream,
writer: Writer,
}
impl SendStream {
pub(super) fn new(stream: WebTransportSendStream) -> Result<Self, Error> {
let writer = Writer::new(&stream)?;
Ok(Self { stream, writer })
}
pub async fn write(&mut self, buf: &[u8]) -> Result<(), Error> {
self.writer
.write(&Uint8Array::from(buf))
.await
.map_err(Into::into)
}
pub async fn write_buf<B: Buf>(&mut self, buf: &mut B) -> Result<usize, Error> {
let chunk = buf.chunk();
let size = chunk.len();
self.writer.write(&Uint8Array::from(chunk)).await?;
buf.advance(size);
Ok(size)
}
pub fn reset(&mut self, reason: &str) {
self.writer.abort(reason);
}
pub fn finish(&mut self) -> Result<(), Error> {
self.writer.close();
Ok(())
}
pub fn set_priority(&mut self, priority: i32) {
Reflect::set(&self.stream, &"sendOrder".into(), &priority.into())
.expect("failed to set priority");
}
pub async fn closed(&self) -> Result<Option<u8>, Error> {
let err = match self.writer.closed().await {
Ok(()) => return Ok(None),
Err(err) => Error::from(err),
};
if let Error::Stream(err) = &err {
if let Some(code) = err.stream_error_code() {
return Ok(Some(code));
}
}
Err(err)
}
}
impl Drop for SendStream {
fn drop(&mut self) {
self.writer.close();
}
}