script/dom/stream/
readablestreamgenericreader.rs1use std::rc::Rc;
6
7use js::jsval::UndefinedValue;
8use js::rust::HandleValue as SafeHandleValue;
9
10use super::readablestream::ReaderType;
11use crate::dom::bindings::error::{Error, ErrorToJsval, Fallible};
12use crate::dom::bindings::reflector::DomGlobal;
13use crate::dom::bindings::root::{DomRoot, MutNullableDom};
14use crate::dom::globalscope::GlobalScope;
15use crate::dom::promise::Promise;
16use crate::dom::stream::readablestreambyobreader::ReadableStreamBYOBReader;
17use crate::dom::stream::readablestreamdefaultreader::ReadableStreamDefaultReader;
18use crate::dom::types::ReadableStream;
19use crate::script_runtime::CanGc;
20
21pub(crate) trait ReadableStreamGenericReader {
23 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
25 fn generic_initialize(&self, global: &GlobalScope, stream: &ReadableStream, can_gc: CanGc) {
26 self.set_stream(Some(stream));
28
29 let reader_type = if let Some(default_reader) = self.as_default_reader() {
31 ReaderType::Default(MutNullableDom::new(Some(default_reader)))
32 } else if let Some(byob_reader) = self.as_byob_reader() {
33 ReaderType::BYOB(MutNullableDom::new(Some(byob_reader)))
34 } else {
35 unreachable!("Reader must be either Default or BYOB.");
36 };
37 stream.set_reader(Some(reader_type));
38
39 if stream.is_readable() {
40 self.set_closed_promise(Promise::new(global, can_gc));
43 } else if stream.is_closed() {
44 let cx = GlobalScope::get_cx();
47 self.set_closed_promise(Promise::new_resolved(global, cx, (), can_gc));
48 } else {
49 assert!(stream.is_errored());
51
52 let cx = GlobalScope::get_cx();
54 rooted!(in(*cx) let mut error = UndefinedValue());
55 stream.get_stored_error(error.handle_mut());
56 self.set_closed_promise(Promise::new_rejected(global, cx, error.handle(), can_gc));
57
58 self.get_closed_promise().set_promise_is_handled();
60 }
61 }
62
63 fn reader_generic_cancel(
65 &self,
66 cx: &mut js::context::JSContext,
67 global: &GlobalScope,
68 reason: SafeHandleValue,
69 ) -> Rc<Promise> {
70 let stream = self.get_stream();
72
73 let stream =
75 stream.expect("Reader should have a stream when generic cancel is called into.");
76
77 stream.cancel(cx, global, reason)
79 }
80
81 fn generic_release(&self, can_gc: CanGc) -> Fallible<()> {
83 assert!(self.get_stream().is_some());
87
88 if let Some(stream) = self.get_stream() {
89 if self.as_default_reader().is_some() {
91 assert!(stream.has_default_reader());
92 } else {
93 assert!(stream.has_byob_reader());
94 }
95
96 if stream.is_readable() {
97 self.get_closed_promise().reject_error(
99 Error::Type(c"stream state is not readable".to_owned()),
100 can_gc,
101 );
102 } else {
103 let cx = GlobalScope::get_cx();
105 rooted!(in(*cx) let mut error = UndefinedValue());
106 Error::Type(c"Cannot release lock due to stream state.".to_owned()).to_jsval(
107 cx,
108 &stream.global(),
109 error.handle_mut(),
110 can_gc,
111 );
112
113 self.set_closed_promise(Promise::new_rejected(
114 &stream.global(),
115 cx,
116 error.handle(),
117 can_gc,
118 ));
119 }
120 self.get_closed_promise().set_promise_is_handled();
122
123 stream
125 .perform_release_steps()
126 .expect("Stream should have a controller");
127
128 stream.set_reader(None);
130 self.set_stream(None);
132 }
133 Ok(())
134 }
135
136 fn closed(&self) -> Rc<Promise> {
138 self.get_closed_promise()
139 }
140
141 fn generic_cancel(
143 &self,
144 cx: &mut js::context::JSContext,
145 global: &GlobalScope,
146 reason: SafeHandleValue,
147 ) -> Rc<Promise> {
148 if self.get_stream().is_none() {
149 let promise = Promise::new2(cx, global);
152 promise.reject_error(
153 Error::Type(c"stream is undefined".to_owned()),
154 CanGc::from_cx(cx),
155 );
156 promise
157 } else {
158 self.reader_generic_cancel(cx, global, reason)
160 }
161 }
162
163 fn set_stream(&self, stream: Option<&ReadableStream>);
164
165 fn get_stream(&self) -> Option<DomRoot<ReadableStream>>;
166
167 fn set_closed_promise(&self, promise: Rc<Promise>);
168
169 fn get_closed_promise(&self) -> Rc<Promise>;
170
171 fn as_default_reader(&self) -> Option<&ReadableStreamDefaultReader> {
172 None
173 }
174
175 fn as_byob_reader(&self) -> Option<&ReadableStreamBYOBReader> {
176 None
177 }
178}