11import _CJavaScriptKit
22
3+ public protocol JSBridgedType : JSValueCodable , CustomStringConvertible {
4+ static var constructor : JSFunction ? { get }
5+
6+ var objectRef : JSObject { get }
7+ init ( objectRef: JSObject )
8+ }
9+
10+ extension JSBridgedType {
11+ public var description : String {
12+ return objectRef. toString!( ) . fromJSValue ( ) !
13+ }
14+ }
15+
316public protocol JSValueConvertible {
417 func jsValue( ) -> JSValue
518}
619
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+
845 public func jsValue( ) -> JSValue { self }
946}
1047
@@ -16,20 +53,20 @@ extension Int: JSValueConvertible {
1653 public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
1754}
1855
19- extension Int8 : JSValueConvertible {
56+ extension UInt : JSValueConvertible {
2057 public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
2158}
2259
23- extension Int16 : JSValueConvertible {
60+ extension Float : JSValueConvertible {
2461 public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
2562}
2663
27- extension Int32 : JSValueConvertible {
28- public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
64+ extension Double : JSValueConvertible {
65+ public func jsValue( ) -> JSValue { . number( self ) }
2966}
3067
31- extension UInt : JSValueConvertible {
32- public func jsValue( ) -> JSValue { . number ( Double ( self ) ) }
68+ extension String : JSValueConvertible {
69+ public func jsValue( ) -> JSValue { . string ( self ) }
3370}
3471
3572extension UInt8 : JSValueConvertible {
@@ -41,22 +78,30 @@ extension UInt16: JSValueConvertible {
4178}
4279
4380extension UInt32 : JSValueConvertible {
44- public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
81+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
4582}
4683
47- extension Float : JSValueConvertible {
84+ extension UInt64 : JSValueConvertible {
4885 public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
4986}
5087
51- extension Double : JSValueConvertible {
52- public func jsValue( ) -> JSValue { . number( self ) }
88+ extension Int8 : JSValueConvertible {
89+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
5390}
5491
55- extension String : JSValueConvertible {
56- public func jsValue( ) -> JSValue { . string( self ) }
92+ extension Int16 : JSValueConvertible {
93+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
94+ }
95+
96+ extension Int32 : JSValueConvertible {
97+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
5798}
5899
59- extension JSObject : JSValueConvertible {
100+ extension Int64 : JSValueConvertible {
101+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
102+ }
103+
104+ extension JSObject : JSValueCodable {
60105 // `JSObject.jsValue` is defined in JSObject.swift to be able to overridden
61106 // from `JSFunction`
62107}
@@ -79,24 +124,80 @@ extension Dictionary: JSValueConvertible where Value == JSValueConvertible, Key
79124 }
80125}
81126
82- private let Array = JSObject . global. Array. function!
127+ private let NativeJSArray = JSObject . global. Array. function!
128+ extension Dictionary : JSValueConstructible where Value: JSValueConstructible , Key == String {
129+ public static func construct( from value: JSValue ) -> Self ? {
130+ if let objectRef = value. object,
131+ let keys: [ String ] = Object . keys!( objectRef. jsValue ( ) ) . fromJSValue ( ) {
132+ var entries = [ ( String, Value) ] ( )
133+ entries. reserveCapacity ( keys. count)
134+ for key in keys {
135+ guard let value: Value = objectRef [ key] . fromJSValue ( ) else {
136+ return nil
137+ }
138+ entries. append ( ( key, value) )
139+ }
140+ return Dictionary ( uniqueKeysWithValues: entries)
141+ }
142+ return nil
143+ }
144+ }
145+
146+ extension Optional : JSValueConstructible where Wrapped: JSValueConstructible {
147+ public static func construct( from value: JSValue ) -> Self ? {
148+ switch value {
149+ case . null, . undefined:
150+ return nil
151+ default :
152+ return Wrapped . construct ( from: value)
153+ }
154+ }
155+ }
156+
157+ extension Optional : JSValueConvertible where Wrapped: JSValueConvertible {
158+ public func jsValue( ) -> JSValue {
159+ switch self {
160+ case . none: return . null
161+ case let . some( wrapped) : return wrapped. jsValue ( )
162+ }
163+ }
164+ }
83165
84166extension Array where Element: JSValueConvertible {
85167 public func jsValue( ) -> JSValue {
86- Swift . Array < JSValueConvertible > . jsValue ( self ) ( )
168+ Array < JSValueConvertible > . jsValue ( self ) ( )
87169 }
88170}
89171
90172extension Array : JSValueConvertible where Element == JSValueConvertible {
91173 public func jsValue( ) -> JSValue {
92- let array = Array . new ( count)
174+ let array = NativeJSArray . new ( count)
93175 for (index, element) in enumerated ( ) {
94176 array [ index] = element. jsValue ( )
95177 }
96178 return . object( array)
97179 }
98180}
99181
182+ extension Array : JSValueConstructible where Element: JSValueConstructible {
183+ public static func construct( from value: JSValue ) -> [ Element ] ? {
184+ if let objectRef = value. object,
185+ objectRef. isInstanceOf ( JSObject . global. Array. function!) {
186+ let count : Int = objectRef. length. fromJSValue ( ) !
187+ var array = [ Element] ( )
188+ array. reserveCapacity ( count)
189+
190+ for i in 0 ..< count {
191+ guard let value: Element = objectRef [ i] . fromJSValue ( ) else { return nil }
192+ array. append ( value)
193+ }
194+
195+ return array
196+ }
197+ return nil
198+ }
199+ }
200+
100201extension RawJSValue : JSValueConvertible {
101202 public func jsValue( ) -> JSValue {
102203 switch kind {
@@ -192,6 +293,6 @@ extension Array where Element == JSValueConvertible {
192293
193294extension Array where Element: JSValueConvertible {
194295 func withRawJSValues< T> ( _ body: ( [ RawJSValue ] ) -> T ) -> T {
195- Swift . Array < JSValueConvertible > . withRawJSValues ( self ) ( body)
296+ Array < JSValueConvertible > . withRawJSValues ( self ) ( body)
196297 }
197298}
0 commit comments