@@ -7,16 +7,13 @@ use wasm_bindgen_futures::{future_to_promise, JsFuture};
77
88use rustpython_vm:: function:: { OptionalArg , PyFuncArgs } ;
99use rustpython_vm:: obj:: {
10- objdict:: PyDictRef ,
11- objfunction:: PyFunction ,
12- objint,
13- objstr:: { self , PyStringRef } ,
10+ objdict:: PyDictRef , objfunction:: PyFunctionRef , objint:: PyIntRef , objstr:: PyStringRef ,
1411 objtype:: PyClassRef ,
1512} ;
16- use rustpython_vm:: pyobject:: { PyObject , PyObjectRef , PyRef , PyResult , PyValue , TypeProtocol } ;
13+ use rustpython_vm:: pyobject:: { PyObject , PyObjectRef , PyRef , PyResult , PyValue } ;
1714use rustpython_vm:: VirtualMachine ;
1815
19- use crate :: { convert, vm_class:: AccessibleVM , wasm_builtins:: window} ;
16+ use crate :: { convert, vm_class:: weak_vm , wasm_builtins:: window} ;
2017
2118enum FetchResponseFormat {
2219 Json ,
@@ -42,50 +39,62 @@ impl FetchResponseFormat {
4239 }
4340}
4441
45- fn browser_fetch ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
46- arg_check ! ( vm, args, required = [ ( url, Some ( vm. ctx. str_type( ) ) ) ] ) ;
42+ #[ derive( FromArgs ) ]
43+ struct FetchArgs {
44+ #[ pyarg( keyword_only, default = "None" ) ]
45+ response_format : Option < PyStringRef > ,
46+ #[ pyarg( keyword_only, default = "None" ) ]
47+ method : Option < PyStringRef > ,
48+ #[ pyarg( keyword_only, default = "None" ) ]
49+ headers : Option < PyDictRef > ,
50+ #[ pyarg( keyword_only, default = "None" ) ]
51+ body : Option < PyObjectRef > ,
52+ #[ pyarg( keyword_only, default = "None" ) ]
53+ content_type : Option < PyStringRef > ,
54+ }
4755
48- let response_format =
49- args. get_optional_kwarg_with_type ( "response_format" , vm. ctx . str_type ( ) , vm) ?;
50- let method = args. get_optional_kwarg_with_type ( "method" , vm. ctx . str_type ( ) , vm) ?;
51- let headers = args. get_optional_kwarg_with_type ( "headers" , vm. ctx . dict_type ( ) , vm) ?;
52- let body = args. get_optional_kwarg ( "body" ) ;
53- let content_type = args. get_optional_kwarg_with_type ( "content_type" , vm. ctx . str_type ( ) , vm) ?;
56+ fn browser_fetch ( url : PyStringRef , args : FetchArgs , vm : & VirtualMachine ) -> PyResult {
57+ let FetchArgs {
58+ response_format,
59+ method,
60+ headers,
61+ body,
62+ content_type,
63+ } = args;
5464
5565 let response_format = match response_format {
56- Some ( s) => FetchResponseFormat :: from_str ( vm, & objstr :: get_value ( & s ) ) ?,
66+ Some ( s) => FetchResponseFormat :: from_str ( vm, s . as_str ( ) ) ?,
5767 None => FetchResponseFormat :: Text ,
5868 } ;
5969
6070 let mut opts = web_sys:: RequestInit :: new ( ) ;
6171
6272 match method {
63- Some ( s) => opts. method ( & objstr :: get_value ( & s ) ) ,
73+ Some ( s) => opts. method ( s . as_str ( ) ) ,
6474 None => opts. method ( "GET" ) ,
6575 } ;
6676
6777 if let Some ( body) = body {
6878 opts. body ( Some ( & convert:: py_to_js ( vm, body) ) ) ;
6979 }
7080
71- let request = web_sys:: Request :: new_with_str_and_init ( & objstr :: get_value ( url) , & opts)
81+ let request = web_sys:: Request :: new_with_str_and_init ( url. as_str ( ) , & opts)
7282 . map_err ( |err| convert:: js_py_typeerror ( vm, err) ) ?;
7383
7484 if let Some ( headers) = headers {
7585 let h = request. headers ( ) ;
76- let headers: PyDictRef = headers. downcast ( ) . unwrap ( ) ;
7786 for ( key, value) in headers. get_key_value_pairs ( ) {
78- let key = & vm. to_str ( & key) ?. value ;
79- let value = & vm. to_str ( & value) ?. value ;
80- h. set ( key, value)
87+ let key = vm. to_str ( & key) ?;
88+ let value = vm. to_str ( & value) ?;
89+ h. set ( key. as_str ( ) , value. as_str ( ) )
8190 . map_err ( |err| convert:: js_py_typeerror ( vm, err) ) ?;
8291 }
8392 }
8493
8594 if let Some ( content_type) = content_type {
8695 request
8796 . headers ( )
88- . set ( "Content-Type" , & objstr :: get_value ( & content_type) )
97+ . set ( "Content-Type" , content_type. as_str ( ) )
8998 . map_err ( |err| convert:: js_py_typeerror ( vm, err) ) ?;
9099 }
91100
@@ -104,9 +113,7 @@ fn browser_fetch(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
104113 Ok ( PyPromise :: from_future ( future) . into_ref ( vm) . into_object ( ) )
105114}
106115
107- fn browser_request_animation_frame ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
108- arg_check ! ( vm, args, required = [ ( func, Some ( vm. ctx. function_type( ) ) ) ] ) ;
109-
116+ fn browser_request_animation_frame ( func : PyFunctionRef , vm : & VirtualMachine ) -> PyResult {
110117 use std:: { cell:: RefCell , rc:: Rc } ;
111118
112119 // this basic setup for request_animation_frame taken from:
@@ -115,18 +122,16 @@ fn browser_request_animation_frame(vm: &VirtualMachine, args: PyFuncArgs) -> PyR
115122 let f = Rc :: new ( RefCell :: new ( None ) ) ;
116123 let g = f. clone ( ) ;
117124
118- let func = func. clone ( ) ;
119-
120- let acc_vm = AccessibleVM :: from ( vm) ;
125+ let weak_vm = weak_vm ( vm) ;
121126
122127 * g. borrow_mut ( ) = Some ( Closure :: wrap ( Box :: new ( move |time : f64 | {
123- let stored_vm = acc_vm
128+ let stored_vm = weak_vm
124129 . upgrade ( )
125130 . expect ( "that the vm is valid from inside of request_animation_frame" ) ;
126131 let vm = & stored_vm. vm ;
127132 let func = func. clone ( ) ;
128133 let args = vec ! [ vm. ctx. new_float( time) ] ;
129- let _ = vm. invoke ( func, args) ;
134+ let _ = vm. invoke ( func. into_object ( ) , args) ;
130135
131136 let closure = f. borrow_mut ( ) . take ( ) ;
132137 drop ( closure) ;
@@ -141,10 +146,8 @@ fn browser_request_animation_frame(vm: &VirtualMachine, args: PyFuncArgs) -> PyR
141146 Ok ( vm. ctx . new_int ( id) )
142147}
143148
144- fn browser_cancel_animation_frame ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
145- arg_check ! ( vm, args, required = [ ( id, Some ( vm. ctx. int_type( ) ) ) ] ) ;
146-
147- let id = objint:: get_value ( id) . to_i32 ( ) . ok_or_else ( || {
149+ fn browser_cancel_animation_frame ( id : PyIntRef , vm : & VirtualMachine ) -> PyResult {
150+ let id = id. as_bigint ( ) . to_i32 ( ) . ok_or_else ( || {
148151 vm. new_exception (
149152 vm. ctx . exceptions . value_error . clone ( ) ,
150153 "Integer too large to convert to i32 for animationFrame id" . into ( ) ,
@@ -186,14 +189,14 @@ impl PyPromise {
186189
187190 fn then (
188191 zelf : PyPromiseRef ,
189- on_fulfill : PyRef < PyFunction > ,
190- on_reject : OptionalArg < PyRef < PyFunction > > ,
192+ on_fulfill : PyFunctionRef ,
193+ on_reject : OptionalArg < PyFunctionRef > ,
191194 vm : & VirtualMachine ,
192195 ) -> PyPromiseRef {
193- let acc_vm = AccessibleVM :: from ( vm) ;
196+ let weak_vm = weak_vm ( vm) ;
194197
195198 let ret_future = JsFuture :: from ( zelf. value . clone ( ) ) . then ( move |res| {
196- let stored_vm = & acc_vm
199+ let stored_vm = & weak_vm
197200 . upgrade ( )
198201 . expect ( "that the vm is valid when the promise resolves" ) ;
199202 let vm = & stored_vm. vm ;
@@ -217,16 +220,12 @@ impl PyPromise {
217220 PyPromise :: from_future ( ret_future) . into_ref ( vm)
218221 }
219222
220- fn catch (
221- zelf : PyPromiseRef ,
222- on_reject : PyRef < PyFunction > ,
223- vm : & VirtualMachine ,
224- ) -> PyPromiseRef {
225- let acc_vm = AccessibleVM :: from ( vm) ;
223+ fn catch ( zelf : PyPromiseRef , on_reject : PyFunctionRef , vm : & VirtualMachine ) -> PyPromiseRef {
224+ let weak_vm = weak_vm ( vm) ;
226225
227226 let ret_future = JsFuture :: from ( zelf. value . clone ( ) ) . then ( move |res| {
228227 res. or_else ( |err| {
229- let stored_vm = acc_vm
228+ let stored_vm = weak_vm
230229 . upgrade ( )
231230 . expect ( "that the vm is valid when the promise resolves" ) ;
232231 let vm = & stored_vm. vm ;
@@ -303,41 +302,31 @@ impl Element {
303302 }
304303}
305304
306- fn browser_alert ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
307- arg_check ! ( vm, args, required = [ ( message, Some ( vm. ctx. str_type( ) ) ) ] ) ;
308-
305+ fn browser_alert ( message : PyStringRef , vm : & VirtualMachine ) -> PyResult {
309306 window ( )
310- . alert_with_message ( & objstr :: get_value ( message) )
307+ . alert_with_message ( message. as_str ( ) )
311308 . expect ( "alert() not to fail" ) ;
312309
313310 Ok ( vm. get_none ( ) )
314311}
315312
316- fn browser_confirm ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
317- arg_check ! ( vm, args, required = [ ( message, Some ( vm. ctx. str_type( ) ) ) ] ) ;
318-
313+ fn browser_confirm ( message : PyStringRef , vm : & VirtualMachine ) -> PyResult {
319314 let result = window ( )
320- . confirm_with_message ( & objstr :: get_value ( message) )
315+ . confirm_with_message ( message. as_str ( ) )
321316 . expect ( "confirm() not to fail" ) ;
322317
323318 Ok ( vm. new_bool ( result) )
324319}
325320
326- fn browser_prompt ( vm : & VirtualMachine , args : PyFuncArgs ) -> PyResult {
327- arg_check ! (
328- vm,
329- args,
330- required = [ ( message, Some ( vm. ctx. str_type( ) ) ) ] ,
331- optional = [ ( default , Some ( vm. ctx. str_type( ) ) ) ]
332- ) ;
333-
334- let result = if let Some ( default) = default {
335- window ( ) . prompt_with_message_and_default (
336- & objstr:: get_value ( message) ,
337- & objstr:: get_value ( default) ,
338- )
321+ fn browser_prompt (
322+ message : PyStringRef ,
323+ default : OptionalArg < PyStringRef > ,
324+ vm : & VirtualMachine ,
325+ ) -> PyResult {
326+ let result = if let OptionalArg :: Present ( default) = default {
327+ window ( ) . prompt_with_message_and_default ( message. as_str ( ) , default. as_str ( ) )
339328 } else {
340- window ( ) . prompt_with_message ( & objstr :: get_value ( message) )
329+ window ( ) . prompt_with_message ( message. as_str ( ) )
341330 } ;
342331
343332 let result = match result. expect ( "prompt() not to fail" ) {
0 commit comments