script/dom/stream/
readablestreamgenericreader.rs1use js::context::JSContext;
6use js::jsval::UndefinedValue;
7use js::rust::HandleValue as SafeHandleValue;
8
9use super::readablestream::ReaderType;
10use crate::dom::bindings::error::{Error, ErrorToJsval, Fallible};
11use crate::dom::bindings::reflector::DomGlobal;
12use crate::dom::bindings::root::{DomRoot, MutNullableDom};
13use crate::dom::globalscope::GlobalScope;
14use crate::dom::promise::{Promise, RootedPromise};
15use crate::dom::stream::readablestreambyobreader::ReadableStreamBYOBReader;
16use crate::dom::stream::readablestreamdefaultreader::ReadableStreamDefaultReader;
17use crate::dom::types::ReadableStream;
18
19pub(crate) trait ReadableStreamGenericReader {
21 #[cfg_attr(crown, expect(crown::unrooted_must_root))]
23 fn generic_initialize(
24 &self,
25 cx: &mut JSContext,
26 global: &GlobalScope,
27 stream: &ReadableStream,
28 ) {
29 self.set_stream(Some(stream));
31
32 let reader_type = if let Some(default_reader) = self.as_default_reader() {
34 ReaderType::Default(MutNullableDom::new(Some(default_reader)))
35 } else if let Some(byob_reader) = self.as_byob_reader() {
36 ReaderType::BYOB(MutNullableDom::new(Some(byob_reader)))
37 } else {
38 unreachable!("Reader must be either Default or BYOB.");
39 };
40 stream.set_reader(Some(reader_type));
41
42 if stream.is_readable() {
43 self.set_closed_promise(&Promise::new_rooted(cx, global));
46 } else if stream.is_closed() {
47 self.set_closed_promise(&Promise::new_resolved_rooted(cx, global, ()));
50 } else {
51 assert!(stream.is_errored());
53
54 rooted!(&in(cx) let mut error = UndefinedValue());
56 stream.get_stored_error(error.handle_mut());
57 self.set_closed_promise(&Promise::new_rejected_rooted(cx, global, error.handle()));
58
59 self.get_closed_promise(cx).set_promise_is_handled(cx);
61 }
62 }
63
64 fn reader_generic_cancel(
66 &self,
67 cx: &mut JSContext,
68 global: &GlobalScope,
69 reason: SafeHandleValue,
70 ) -> RootedPromise {
71 let stream = self.get_stream();
73
74 let stream =
76 stream.expect("Reader should have a stream when generic cancel is called into.");
77
78 stream.cancel(cx, global, reason)
80 }
81
82 fn generic_release(&self, cx: &mut JSContext) -> Fallible<()> {
84 assert!(self.get_stream().is_some());
88
89 if let Some(stream) = self.get_stream() {
90 if self.as_default_reader().is_some() {
92 assert!(stream.has_default_reader());
93 } else {
94 assert!(stream.has_byob_reader());
95 }
96
97 if stream.is_readable() {
98 self.get_closed_promise(cx)
100 .reject_error(cx, Error::Type(c"stream state is not readable".to_owned()));
101 } else {
102 rooted!(&in(cx) let mut error = UndefinedValue());
104 Error::Type(c"Cannot release lock due to stream state.".to_owned()).to_jsval(
105 cx,
106 &stream.global(),
107 error.handle_mut(),
108 );
109
110 self.set_closed_promise(&Promise::new_rejected_rooted(
111 cx,
112 &stream.global(),
113 error.handle(),
114 ));
115 }
116 self.get_closed_promise(cx).set_promise_is_handled(cx);
118
119 stream
121 .perform_release_steps()
122 .expect("Stream should have a controller");
123
124 stream.set_reader(None);
126 self.set_stream(None);
128 }
129 Ok(())
130 }
131
132 fn closed(&self, cx: &JSContext) -> RootedPromise {
134 self.get_closed_promise(cx)
135 }
136
137 fn generic_cancel(
139 &self,
140 cx: &mut JSContext,
141 global: &GlobalScope,
142 reason: SafeHandleValue,
143 ) -> RootedPromise {
144 if self.get_stream().is_none() {
145 let promise = Promise::new_rooted(cx, global);
148 promise.reject_error(cx, Error::Type(c"stream is undefined".to_owned()));
149 promise
150 } else {
151 self.reader_generic_cancel(cx, global, reason)
153 }
154 }
155
156 fn set_stream(&self, stream: Option<&ReadableStream>);
157
158 fn get_stream(&self) -> Option<DomRoot<ReadableStream>>;
159
160 fn set_closed_promise(&self, promise: &RootedPromise);
161
162 fn get_closed_promise(&self, cx: &JSContext) -> RootedPromise;
163
164 fn as_default_reader(&self) -> Option<&ReadableStreamDefaultReader> {
165 None
166 }
167
168 fn as_byob_reader(&self) -> Option<&ReadableStreamBYOBReader> {
169 None
170 }
171}