@@ -7,125 +7,24 @@ use expression::Object;
7
7
use expression:: Value ;
8
8
use expression:: parse;
9
9
use expression:: parse:: literal:: Literal ;
10
+ use crate :: convert:: { js_value_to_object, value_to_js_object} ;
10
11
use crate :: DataSource ;
11
12
12
13
#[ wasm_bindgen( js_name=Context ) ]
13
14
pub struct Context {
14
- cx : expression:: Context < DataSource > ,
15
+ expr : expression:: Context < DataSource > ,
15
16
global_context : Rc < WasmRefCell < Object > >
16
17
}
17
18
18
- /// This function attempts to convert a JS value into its native equivalent.
19
- ///
20
- /// * `js_sys::String`s => `expression::Object::String`
21
- /// * `js_sys::Array`s => `expression::Object::List`
22
- /// * `js_sys::Object`s => `expression::Object::AssociativeArray`
23
- /// * `js_sys::Object + { [Symbol.address]: Address }`s => `expression::Object::Address` !
24
- /// * `js_sys::Null` => `expression::Object::Nothing`
25
- /// * `js_sys::falsy()` => `expression::Object::Boolean(false)`
26
- /// * `js_sys::truthy()` => `expression::Object::Boolean(true)`
27
- ///
28
- /// > **Note:** Nested values such as those in lists or associative arrays which
29
- /// fail automatic conversation will be dropped silently.
30
- pub ( crate ) fn js_value_to_object ( value : JsValue ) -> Option < Object > {
31
- if let Some ( number) = value. as_f64 ( ) {
32
- return Some ( Object :: Number ( number) ) ;
33
- }
34
-
35
- Some ( match value {
36
- value if value. is_null ( ) || value. is_undefined ( ) => Object :: Nothing ,
37
-
38
- value if value. is_string ( ) => Object :: String ( value. as_string ( ) ?) ,
39
- value if value. is_array ( ) => Object :: List ( js_sys:: Array :: from ( & value)
40
- . into_iter ( )
41
- . flat_map ( js_value_to_object)
42
- . collect ( ) ) ,
43
-
44
- value if value. is_function ( ) => {
45
- let value = value. clone ( ) ;
46
- Object :: function ( move |args| {
47
- let args = js_sys:: Array :: from_iter ( args. into_iter ( )
48
- . map ( value_to_js_object)
49
- . map ( |i| i. ok_or ( Into :: < Error > :: into ( ManualError :: ConversionFailed ) ) )
50
- . collect :: < Result < Vec < _ > > > ( ) ?
51
- . into_iter ( ) ) ;
52
- let result = js_sys:: Function :: from ( value. clone ( ) ) . call1 ( & JsValue :: null ( ) , & JsValue :: from ( args) )
53
- . unwrap_throw ( ) ;
54
- js_value_to_object ( result)
55
- . ok_or ( ManualError :: ConversionFailed . into ( ) )
56
- } )
57
- } ,
58
-
59
- // TODO: Detect Addresses
60
- value if value. is_object ( ) => expression:: Object :: AssociativeArray ( js_sys:: Reflect :: own_keys ( & value) . ok ( ) ?
61
- . into_iter ( )
62
- . flat_map ( |i| match i {
63
- value if value. is_string ( ) || value. is_symbol ( ) => value. as_string ( ) ,
64
- _ => None
65
- } )
66
- . flat_map ( |key| js_value_to_object ( js_sys:: Reflect :: get ( & value, & JsValue :: from_str ( & key) ) . ok ( ) ?)
67
- . map ( |value| ( key. clone ( ) , value) ) )
68
- . collect ( ) ) ,
69
-
70
- value if value. is_falsy ( ) => Object :: Boolean ( false ) ,
71
- value if value. is_truthy ( ) => Object :: Boolean ( true ) ,
72
- _ => None ?,
73
- } )
74
- }
75
-
76
-
77
- /// This function attempts to convert a native value into its JS equivalent.
78
- ///
79
- /// * `js_sys::String`s => `expression::Object::String`
80
- /// * `js_sys::Array`s => `expression::Object::List`
81
- /// * `js_sys::Object`s => `expression::Object::AssociativeArray`
82
- /// * `js_sys::Object + { [Symbol.address]: Address }`s => `expression::Object::Address` !
83
- /// * `js_sys::Null` => `expression::Object::Nothing`
84
- /// * `js_sys::falsy()` => `expression::Object::Boolean(false)`
85
- /// * `js_sys::truthy()` => `expression::Object::Boolean(true)`
86
- ///
87
- /// > **Note:** Nested values such as those in lists or associative arrays which
88
- /// fail automatic conversation will be dropped silently.
89
- pub ( crate ) fn value_to_js_object ( value : Object ) -> Option < JsValue > {
90
- Some ( match value {
91
- Object :: Number ( num) => js_sys:: Number :: from ( num) . into ( ) ,
92
- Object :: Boolean ( bool) => js_sys:: Boolean :: from ( bool) . into ( ) ,
93
- Object :: String ( str) => JsValue :: from_str ( & str) ,
94
- Object :: List ( list) => JsValue :: from ( js_sys:: Array :: from_iter ( list. into_iter ( )
95
- . flat_map ( value_to_js_object) ) ) ,
96
- Object :: AssociativeArray ( arr) => {
97
- let key_map = js_sys:: Object :: new ( ) ;
98
-
99
- for ( key, value) in arr {
100
- js_sys:: Reflect :: set ( & key_map, & JsValue :: from_str ( & key) , & value_to_js_object ( value) ?)
101
- . unwrap_throw ( ) ;
102
- }
103
-
104
- JsValue :: from ( key_map)
105
- } ,
106
- Object :: Nothing => JsValue :: null ( ) ,
107
- Object :: Function ( function) => JsClosure :: new ( move |_args| -> JsValue {
108
- wasm_bindgen:: throw_str ( "Fuck you" ) ;
109
- function ( vec ! [ ] )
110
- . map ( value_to_js_object)
111
- . unwrap_throw ( )
112
- . unwrap_throw ( )
113
- } ) . into ( ) ,
114
- } )
115
- }
116
-
117
19
#[ wasm_bindgen( js_class=Context ) ]
118
20
impl Context {
119
21
#[ wasm_bindgen( constructor) ]
120
- pub fn new ( config : js_sys:: Object ) -> Context {
121
- let cx = DataSource :: from_js ( config ) ;
22
+ pub fn new ( provider : js_sys:: Object ) -> Context {
23
+ let provider = DataSource :: from_js ( provider ) ;
122
24
123
25
Self {
124
- global_context : cx. cx . clone ( ) ,
125
- cx : expression:: Context :: new ( cx)
126
- . with_fn ( "cx" , move |cx, _| {
127
- Ok ( cx. provider ( ) . cx . borrow ( ) . clone ( ) )
128
- } )
26
+ global_context : provider. ephemeral_cx . clone ( ) ,
27
+ expr : expression:: Context :: new ( provider)
129
28
}
130
29
}
131
30
@@ -141,21 +40,21 @@ impl Context {
141
40
wasm_bindgen:: throw_str ( "Object could not be cast to target" ) ;
142
41
} ;
143
42
144
- self . cx . push_global ( name, obj) ;
43
+ self . expr . push_global ( name, obj) ;
145
44
}
146
45
147
- #[ deprecated( note = "Use push_global instead" ) ]
46
+ #[ deprecated( note = "Use pushGlobal instead" ) ]
148
47
#[ wasm_bindgen( js_name = withGlobal) ]
149
48
pub fn with_global ( self , name : js_sys:: JsString , global : JsValue ) -> Self {
150
49
unimplemented ! ( "Use the `pushGlobal` function instead`" )
151
50
}
152
51
153
52
#[ wasm_bindgen( js_name = pushOperator) ]
154
53
pub fn set_operator ( & mut self , operator : crate :: Operator ) {
155
- self . cx . push_operator ( operator. into_operator ( ) ) ;
54
+ self . expr . push_operator ( operator. into_operator ( ) ) ;
156
55
}
157
56
158
- #[ deprecated( note = "Use push_operator instead" ) ]
57
+ #[ deprecated( note = "Use pushOperator instead" ) ]
159
58
#[ wasm_bindgen( js_name = withOperator) ]
160
59
pub fn with_operator ( self , name : js_sys:: JsString , global : JsValue ) -> Self {
161
60
unimplemented ! ( "Use the `pushOperator` function instead" ) ;
@@ -167,10 +66,9 @@ impl Context {
167
66
wasm_bindgen:: throw_str ( "Expression could not be cast to native string" ) ;
168
67
} ;
169
68
170
- * self . global_context . borrow_mut ( ) = js_value_to_object ( cx)
171
- . unwrap_throw ( ) ;
69
+ * self . global_context . borrow_mut ( ) = js_value_to_object ( cx) . unwrap_throw ( ) ;
172
70
173
- let error_message_or_result = self . cx . evaluate ( expr)
71
+ let error_message_or_result = self . expr . evaluate ( expr)
174
72
. map_err ( |error| match error. into_inner ( ) {
175
73
global:: Inner :: ManualError ( ManualError :: InsufficientOperands ( op) ) => format ! ( "The operator '{}' did not receive the required number of operands." , op) ,
176
74
global:: Inner :: ManualError ( ManualError :: CannotCallNonFunctionObject ( ) ) => format ! ( "Object not callable" ) ,
@@ -186,11 +84,8 @@ impl Context {
186
84
Err ( err) => wasm_bindgen:: throw_str ( & err)
187
85
} ;
188
86
189
- if let Some ( res) = value_to_js_object ( res) {
190
- res
191
- } else {
192
- wasm_bindgen:: throw_str ( "Unable to convert result back into JS" ) ;
193
- }
87
+ return value_to_js_object ( res)
88
+ . unwrap_throw ( ) ;
194
89
}
195
90
196
91
#[ wasm_bindgen( js_name="parseStr" ) ]
@@ -235,7 +130,7 @@ impl Context {
235
130
}
236
131
}
237
132
238
- flatten ( & mut match self . cx . parse ( & expr) {
133
+ flatten ( & mut match self . expr . parse ( & expr) {
239
134
Ok ( value) => value,
240
135
Err ( err) => wasm_bindgen:: throw_str ( & format ! ( "{:#?}" , err) )
241
136
} ) . unwrap_or ( vec ! [ ] )
@@ -244,27 +139,14 @@ impl Context {
244
139
#[ wasm_bindgen( js_name="clone" ) ]
245
140
pub fn clone ( & self ) -> Self {
246
141
Self {
247
- cx : self . cx . clone ( ) ,
142
+ expr : self . expr . clone ( ) ,
248
143
global_context : self . global_context . clone ( ) ,
249
144
}
250
145
}
251
146
252
147
#[ wasm_bindgen( js_name="provider" ) ]
253
148
pub fn provider ( & self ) -> JsValue {
254
- self . cx . provider ( ) . inner . clone ( ) . into ( )
255
- }
256
- }
257
-
258
- #[ wasm_bindgen]
259
- struct JsClosure {
260
- closure : Closure < dyn Fn ( ) > ,
261
- }
262
-
263
- impl JsClosure {
264
- pub fn new ( handler : impl Fn ( JsValue ) -> JsValue + ' static ) -> Self {
265
- Self {
266
- closure : Closure :: new ( || { } )
267
- }
149
+ self . expr . provider ( ) . inner . clone ( ) . into ( )
268
150
}
269
151
}
270
152
0 commit comments