33//! See <https://developer.mozilla.org/en-US/docs/Web/API/Headers>.
44#![ allow( clippy:: needless_pass_by_value) ]
55
6+ use boa_engine:: builtins:: iterable:: create_iter_result_object;
67use boa_engine:: interop:: JsClass ;
7- use boa_engine:: object :: builtins :: { JsArray , TypedJsFunction } ;
8+ use boa_engine:: native_function :: NativeFunction ;
89use boa_engine:: object:: FunctionObjectBuilder ;
10+ use boa_engine:: object:: builtins:: { JsArray , TypedJsFunction } ;
911use boa_engine:: property:: PropertyDescriptor ;
1012use boa_engine:: value:: { Convert , TryFromJs } ;
1113use boa_engine:: {
1214 Context , Finalize , JsData , JsObject , JsResult , JsString , JsValue , Trace , boa_class, js_error,
1315 js_string,
1416} ;
15- use boa_engine:: builtins:: iterable:: create_iter_result_object;
16- use boa_engine:: native_function:: NativeFunction ;
1717use http:: header:: HeaderMap as HttpHeaderMap ;
1818use http:: { HeaderName , HeaderValue } ;
1919use std:: cell:: RefCell ;
@@ -44,44 +44,54 @@ enum HeadersIteratorKind {
4444/// - [WHATWG spec](https://fetch.spec.whatwg.org/#headers-class)
4545#[ derive( Debug , Clone , JsData , Trace , Finalize ) ]
4646struct HeadersIterator {
47- headers : JsHeaders ,
47+ headers : Vec < ( JsString , JsString ) > ,
4848 index : usize ,
4949 kind : HeadersIteratorKind ,
5050}
5151
5252impl HeadersIterator {
5353 /// Creates a new Headers iterator.
5454 fn new ( headers : JsHeaders , kind : HeadersIteratorKind ) -> Self {
55+ let headers_vec: Vec < ( JsString , JsString ) > = {
56+ let headers_data = headers. headers . borrow ( ) ;
57+ headers_data
58+ . iter ( )
59+ . map ( |( key, value) | {
60+ (
61+ JsString :: from ( key. as_str ( ) ) ,
62+ JsString :: from ( value. to_str ( ) . unwrap_or_default ( ) ) ,
63+ )
64+ } )
65+ . collect ( )
66+ } ;
67+
5568 Self {
56- headers,
69+ headers : headers_vec ,
5770 index : 0 ,
5871 kind,
5972 }
6073 }
6174
6275 /// Gets the next entry in the headers iterator.
63- fn next ( & mut self , context : & mut Context ) -> JsResult < JsValue > {
64- let headers_data = self . headers . headers . borrow ( ) ;
65- let headers_vec: Vec < _ > = headers_data. iter ( ) . collect ( ) ;
66-
67- if self . index >= headers_vec. len ( ) {
68- return Ok ( create_iter_result_object ( JsValue :: undefined ( ) , true , context) ) ;
76+ fn next ( & mut self , context : & mut Context ) -> JsValue {
77+ if self . index >= self . headers . len ( ) {
78+ return create_iter_result_object ( JsValue :: undefined ( ) , true , context) ;
6979 }
7080
71- let ( key, value) = headers_vec [ self . index ] ;
81+ let ( key, value) = & self . headers [ self . index ] ;
7282 self . index += 1 ;
7383
7484 let value_obj = match self . kind {
7585 HeadersIteratorKind :: Entries => {
76- let key_val: JsValue = JsString :: from ( key. as_str ( ) ) . into ( ) ;
77- let val_val: JsValue = JsString :: from ( value. to_str ( ) . unwrap_or_default ( ) ) . into ( ) ;
86+ let key_val: JsValue = key. clone ( ) . into ( ) ;
87+ let val_val: JsValue = value. clone ( ) . into ( ) ;
7888 JsArray :: from_iter ( [ key_val, val_val] , context) . into ( )
7989 }
80- HeadersIteratorKind :: Keys => JsString :: from ( key. as_str ( ) ) . into ( ) ,
81- HeadersIteratorKind :: Values => JsString :: from ( value. to_str ( ) . unwrap_or_default ( ) ) . into ( ) ,
90+ HeadersIteratorKind :: Keys => key. clone ( ) . into ( ) ,
91+ HeadersIteratorKind :: Values => value. clone ( ) . into ( ) ,
8292 } ;
8393
84- Ok ( create_iter_result_object ( value_obj, false , context) )
94+ create_iter_result_object ( value_obj, false , context)
8595 }
8696}
8797
@@ -122,12 +132,19 @@ fn headers_iterator_next(
122132 . and_then ( JsObject :: downcast_mut :: < HeadersIterator > )
123133 . ok_or_else ( || js_error ! ( TypeError : "`this` is not a Headers iterator" ) ) ?;
124134
125- iterator. next ( context)
135+ Ok ( iterator. next ( context) )
126136}
127137
128138/// Creates a Headers iterator object wrapper.
129- fn create_headers_iterator_object ( iterator : HeadersIterator , context : & mut Context ) -> JsValue {
130- let proto = context. intrinsics ( ) . objects ( ) . iterator_prototypes ( ) . iterator ( ) ;
139+ fn create_headers_iterator_object (
140+ iterator : HeadersIterator ,
141+ context : & mut Context ,
142+ ) -> JsResult < JsValue > {
143+ let proto = context
144+ . intrinsics ( )
145+ . objects ( )
146+ . iterator_prototypes ( )
147+ . iterator ( ) ;
131148 let iterator_obj = JsObject :: from_proto_and_data ( proto, iterator) ;
132149
133150 let next_fn = FunctionObjectBuilder :: new (
@@ -139,18 +156,17 @@ fn create_headers_iterator_object(iterator: HeadersIterator, context: &mut Conte
139156 . constructor ( false )
140157 . build ( ) ;
141158
142- #[ allow( let_underscore_drop) ]
143- let _ = iterator_obj. define_property_or_throw (
159+ iterator_obj. define_property_or_throw (
144160 js_string ! ( "next" ) ,
145161 PropertyDescriptor :: builder ( )
146162 . value ( next_fn)
147163 . writable ( true )
148164 . enumerable ( false )
149165 . configurable ( true ) ,
150166 context,
151- ) ;
167+ ) ? ;
152168
153- iterator_obj. into ( )
169+ Ok ( iterator_obj. into ( ) )
154170}
155171
156172/// A JavaScript wrapper for the `Headers` object.
@@ -266,10 +282,13 @@ impl JsHeaders {
266282
267283 /// Returns an iterator allowing to go through all key/value pairs contained in this object.
268284 ///
285+ /// # Errors
286+ /// Returns an error if the iterator object cannot be created.
287+ ///
269288 /// More information:
270289 /// - [WHATWG spec](https://fetch.spec.whatwg.org/#headers-class)
271290 #[ boa( method) ]
272- pub fn entries ( this : JsClass < Self > , context : & mut Context ) -> JsValue {
291+ pub fn entries ( this : JsClass < Self > , context : & mut Context ) -> JsResult < JsValue > {
273292 let iterator = HeadersIterator :: new ( this. clone_inner ( ) , HeadersIteratorKind :: Entries ) ;
274293 create_headers_iterator_object ( iterator, context)
275294 }
@@ -348,10 +367,13 @@ impl JsHeaders {
348367 /// Returns an iterator allowing you to go through all keys of the key/value pairs
349368 /// contained in this object.
350369 ///
370+ /// # Errors
371+ /// Returns an error if the iterator object cannot be created.
372+ ///
351373 /// More information:
352374 /// - [WHATWG spec](https://fetch.spec.whatwg.org/#headers-class)
353375 #[ boa( method) ]
354- fn keys ( this : JsClass < Self > , context : & mut Context ) -> JsValue {
376+ fn keys ( this : JsClass < Self > , context : & mut Context ) -> JsResult < JsValue > {
355377 let iterator = HeadersIterator :: new ( this. clone_inner ( ) , HeadersIteratorKind :: Keys ) ;
356378 create_headers_iterator_object ( iterator, context)
357379 }
@@ -367,10 +389,13 @@ impl JsHeaders {
367389
368390 /// Returns an iterator allowing you to go through all values in the Headers object.
369391 ///
392+ /// # Errors
393+ /// Returns an error if the iterator object cannot be created.
394+ ///
370395 /// More information:
371396 /// - [WHATWG spec](https://fetch.spec.whatwg.org/#headers-class)
372397 #[ boa( method) ]
373- pub fn values ( this : JsClass < Self > , context : & mut Context ) -> JsValue {
398+ pub fn values ( this : JsClass < Self > , context : & mut Context ) -> JsResult < JsValue > {
374399 let iterator = HeadersIterator :: new ( this. clone_inner ( ) , HeadersIteratorKind :: Values ) ;
375400 create_headers_iterator_object ( iterator, context)
376401 }
0 commit comments