1
1
import _CJavaScriptKit
2
2
3
+ public protocol JSBridgedType : JSValueCodable , CustomStringConvertible {
4
+ static var constructor : JSFunctionRef ? { get }
5
+
6
+ var objectRef : JSObjectRef { get }
7
+ init ( objectRef: JSObjectRef )
8
+ }
9
+
10
+ extension JSBridgedType {
11
+ public var description : String {
12
+ return objectRef. toString!( ) . fromJSValue ( ) !
13
+ }
14
+ }
15
+
3
16
public protocol JSValueConvertible {
4
17
func jsValue( ) -> JSValue
5
18
}
6
19
7
- extension JSValue : JSValueConvertible {
20
+ public typealias JSValueCodable = JSValueConvertible & JSValueConstructible
21
+
22
+ extension JSBridgedType {
23
+ public static func canDecode( from jsValue: JSValue ) -> Bool {
24
+ if let constructor = Self . constructor {
25
+ return jsValue. isInstanceOf ( constructor)
26
+ } else {
27
+ return jsValue. isObject
28
+ }
29
+ }
30
+
31
+ public init ( jsValue: JSValue ) {
32
+ self . init ( objectRef: jsValue. object!)
33
+ }
34
+
35
+ public func jsValue( ) -> JSValue {
36
+ return JSValue . object ( objectRef)
37
+ }
38
+ }
39
+
40
+ extension JSValue : JSValueCodable {
41
+ public static func construct( from value: JSValue ) -> Self ? {
42
+ return value
43
+ }
44
+
8
45
public func jsValue( ) -> JSValue { self }
9
46
}
10
47
@@ -16,48 +53,56 @@ extension Int: JSValueConvertible {
16
53
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
17
54
}
18
55
19
- extension Int8 : JSValueConvertible {
56
+ extension Double : JSValueConvertible {
57
+ public func jsValue( ) -> JSValue { . number( self ) }
58
+ }
59
+
60
+ extension String : JSValueConvertible {
61
+ public func jsValue( ) -> JSValue { . string( self ) }
62
+ }
63
+
64
+ extension UInt8 : JSValueConvertible {
20
65
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
21
66
}
22
67
23
- extension Int16 : JSValueConvertible {
68
+ extension UInt16 : JSValueConvertible {
24
69
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
25
70
}
26
71
27
- extension Int32 : JSValueConvertible {
72
+ extension UInt32 : JSValueConvertible {
28
73
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
29
74
}
30
75
31
- extension UInt : JSValueConvertible {
76
+ extension UInt64 : JSValueConvertible {
32
77
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
33
78
}
34
79
35
- extension UInt8 : JSValueConvertible {
80
+ extension Int8 : JSValueConvertible {
36
81
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
37
82
}
38
83
39
- extension UInt16 : JSValueConvertible {
84
+ extension Int16 : JSValueConvertible {
40
85
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
41
86
}
42
87
43
- extension Float : JSValueConvertible {
88
+ extension Int32 : JSValueConvertible {
44
89
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
45
90
}
46
91
47
- extension Double : JSValueConvertible {
48
- public func jsValue( ) -> JSValue { . number( self ) }
92
+ extension Int64 : JSValueConvertible {
93
+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
49
94
}
50
95
51
- extension String : JSValueConvertible {
52
- public func jsValue( ) -> JSValue { . string ( self ) }
96
+ extension Float : JSValueConvertible {
97
+ public func jsValue( ) -> JSValue { . number ( Double ( self ) ) }
53
98
}
54
99
55
- extension JSObjectRef : JSValueConvertible {
100
+ extension JSObjectRef : JSValueCodable {
56
101
// `JSObjectRef.jsValue` is defined in JSObjectRef.swift to be able to overridden
57
102
// from `JSFunctionRef`
58
103
}
59
104
60
- private let Object = JSObjectRef . global. Object. function!
105
+ private let JSObject = JSObjectRef . global. Object. function!
61
106
62
107
extension Dictionary where Value: JSValueConvertible , Key == String {
63
108
public func jsValue( ) -> JSValue {
@@ -67,15 +112,53 @@ extension Dictionary where Value: JSValueConvertible, Key == String {
67
112
68
113
extension Dictionary : JSValueConvertible where Value == JSValueConvertible , Key == String {
69
114
public func jsValue( ) -> JSValue {
70
- let object = Object . new ( )
115
+ let object = JSObject . new ( )
71
116
for (key, value) in self {
72
117
object [ key] = value. jsValue ( )
73
118
}
74
119
return . object( object)
75
120
}
76
121
}
77
122
78
- private let Array = JSObjectRef . global. Array. function!
123
+ extension Dictionary : JSValueConstructible where Value: JSValueConstructible , Key == String {
124
+ public static func construct( from value: JSValue ) -> Self ? {
125
+ if let objectRef = value. object,
126
+ let keys: [ String ] = JSObject . keys!( objectRef. jsValue ( ) ) . fromJSValue ( ) {
127
+ var entries = [ ( String, Value) ] ( )
128
+ entries. reserveCapacity ( keys. count)
129
+ for key in keys {
130
+ guard let value: Value = objectRef [ key] . fromJSValue ( ) else {
131
+ return nil
132
+ }
133
+ entries. append ( ( key, value) )
134
+ }
135
+ return Dictionary ( uniqueKeysWithValues: entries)
136
+ }
137
+ return nil
138
+ }
139
+ }
140
+
141
+ extension Optional : JSValueConstructible where Wrapped: JSValueConstructible {
142
+ public static func construct( from value: JSValue ) -> Self ? {
143
+ switch value {
144
+ case . null, . undefined:
145
+ return nil
146
+ default :
147
+ return Wrapped . construct ( from: value)
148
+ }
149
+ }
150
+ }
151
+
152
+ extension Optional : JSValueConvertible where Wrapped: JSValueConvertible {
153
+ public func jsValue( ) -> JSValue {
154
+ switch self {
155
+ case . none: return . null
156
+ case let . some( wrapped) : return wrapped. jsValue ( )
157
+ }
158
+ }
159
+ }
160
+
161
+ private let JSArray = JSObjectRef . global. Array. function!
79
162
80
163
extension Array where Element: JSValueConvertible {
81
164
public func jsValue( ) -> JSValue {
@@ -85,14 +168,33 @@ extension Array where Element: JSValueConvertible {
85
168
86
169
extension Array : JSValueConvertible where Element == JSValueConvertible {
87
170
public func jsValue( ) -> JSValue {
88
- let array = Array . new ( count)
171
+ let array = JSArray . new ( count)
89
172
for (index, element) in enumerated ( ) {
90
173
array [ index] = element. jsValue ( )
91
174
}
92
175
return . object( array)
93
176
}
94
177
}
95
178
179
+ extension Array : JSValueConstructible where Element: JSValueConstructible {
180
+ public static func construct( from value: JSValue ) -> [ Element ] ? {
181
+ if let objectRef = value. object,
182
+ objectRef. isInstanceOf ( JSObjectRef . global. Array. function!) {
183
+ let count : Int = objectRef. length. fromJSValue ( ) !
184
+ var array = [ Element] ( )
185
+ array. reserveCapacity ( count)
186
+
187
+ for i in 0 ..< count {
188
+ guard let value: Element = objectRef [ i] . fromJSValue ( ) else { return nil }
189
+ array. append ( value)
190
+ }
191
+
192
+ return array
193
+ }
194
+ return nil
195
+ }
196
+ }
197
+
96
198
extension RawJSValue : JSValueConvertible {
97
199
public func jsValue( ) -> JSValue {
98
200
switch kind {
@@ -188,6 +290,6 @@ extension Array where Element == JSValueConvertible {
188
290
189
291
extension Array where Element: JSValueConvertible {
190
292
func withRawJSValues< T> ( _ body: ( [ RawJSValue ] ) -> T ) -> T {
191
- Swift . Array < JSValueConvertible > . withRawJSValues ( self ) ( body)
293
+ Array < JSValueConvertible > . withRawJSValues ( self ) ( body)
192
294
}
193
295
}
0 commit comments