@@ -2,20 +2,55 @@ import _CJavaScriptKit
22
33/// `JSValue` represents a value in JavaScript.
44@dynamicMemberLookup
5- public enum JSValue : Equatable {
6- case boolean( Bool )
7- case string( JSString )
8- case number( Double )
9- case object( JSObject )
10- case null
11- case undefined
12- case symbol( JSSymbol )
13- case bigInt( JSBigInt )
5+ public struct JSValue : Equatable {
6+ /// The internal storage of the JSValue, which is intentionally not public
7+ /// to leave the flexibility to change the storage.
8+ internal enum Storage : Equatable {
9+ case boolean( Bool )
10+ case string( JSString )
11+ case number( Double )
12+ case object( JSObject )
13+ case null
14+ case undefined
15+ case symbol( JSSymbol )
16+ case bigInt( JSBigInt )
17+ }
18+
19+ internal var storage : Storage
20+
21+ internal init ( storage: Storage ) {
22+ self . storage = storage
23+ }
24+
25+ public static func boolean( _ value: Bool ) -> JSValue {
26+ . init( storage: . boolean( value) )
27+ }
28+ public static func string( _ value: JSString ) -> JSValue {
29+ . init( storage: . string( value) )
30+ }
31+ public static func number( _ value: Double ) -> JSValue {
32+ . init( storage: . number( value) )
33+ }
34+ public static func object( _ value: JSObject ) -> JSValue {
35+ . init( storage: . object( value) )
36+ }
37+ public static var null : JSValue {
38+ . init( storage: . null)
39+ }
40+ public static var undefined : JSValue {
41+ . init( storage: . undefined)
42+ }
43+ public static func symbol( _ value: JSSymbol ) -> JSValue {
44+ . init( storage: . symbol( value) )
45+ }
46+ public static func bigInt( _ value: JSBigInt ) -> JSValue {
47+ . init( storage: . bigInt( value) )
48+ }
1449
1550 /// Returns the `Bool` value of this JS value if its type is boolean.
1651 /// If not, returns `nil`.
1752 public var boolean : Bool ? {
18- switch self {
53+ switch storage {
1954 case . boolean( let boolean) : return boolean
2055 default : return nil
2156 }
@@ -35,7 +70,7 @@ public enum JSValue: Equatable {
3570 /// If not, returns `nil`.
3671 ///
3772 public var jsString : JSString ? {
38- switch self {
73+ switch storage {
3974 case . string( let string) : return string
4075 default : return nil
4176 }
@@ -44,7 +79,7 @@ public enum JSValue: Equatable {
4479 /// Returns the `Double` value of this JS value if the type is number.
4580 /// If not, returns `nil`.
4681 public var number : Double ? {
47- switch self {
82+ switch storage {
4883 case . number( let number) : return number
4984 default : return nil
5085 }
@@ -53,7 +88,7 @@ public enum JSValue: Equatable {
5388 /// Returns the `JSObject` of this JS value if its type is object.
5489 /// If not, returns `nil`.
5590 public var object : JSObject ? {
56- switch self {
91+ switch storage {
5792 case . object( let object) : return object
5893 default : return nil
5994 }
@@ -65,7 +100,7 @@ public enum JSValue: Equatable {
65100 /// Returns the `JSSymbol` of this JS value if its type is function.
66101 /// If not, returns `nil`.
67102 public var symbol : JSSymbol ? {
68- switch self {
103+ switch storage {
69104 case . symbol( let symbol) : return symbol
70105 default : return nil
71106 }
@@ -74,7 +109,7 @@ public enum JSValue: Equatable {
74109 /// Returns the `JSBigInt` of this JS value if its type is function.
75110 /// If not, returns `nil`.
76111 public var bigInt : JSBigInt ? {
77- switch self {
112+ switch storage {
78113 case . bigInt( let bigInt) : return bigInt
79114 default : return nil
80115 }
@@ -83,13 +118,13 @@ public enum JSValue: Equatable {
83118 /// Returns the `true` if this JS value is null.
84119 /// If not, returns `false`.
85120 public var isNull : Bool {
86- return self == . null
121+ return storage == . null
87122 }
88123
89124 /// Returns the `true` if this JS value is undefined.
90125 /// If not, returns `false`.
91126 public var isUndefined : Bool {
92- return self == . undefined
127+ return storage == . undefined
93128 }
94129}
95130
@@ -132,7 +167,7 @@ extension JSValue {
132167
133168extension JSValue {
134169 public static func string( _ value: String ) -> JSValue {
135- . string( JSString ( value) )
170+ . init ( storage : . string( JSString ( value) ) )
136171 }
137172
138173 /// Deprecated: Please create `JSClosure` directly and manage its lifetime manually.
@@ -161,7 +196,7 @@ extension JSValue {
161196 /// ```
162197 @available ( * , deprecated, message: " Please create JSClosure directly and manage its lifetime manually. " )
163198 public static func function( _ body: @escaping ( [ JSValue ] ) -> JSValue ) -> JSValue {
164- . object( JSClosure ( body) )
199+ . init ( storage : . object( JSClosure ( body) ) )
165200 }
166201
167202 @available (
@@ -171,34 +206,34 @@ extension JSValue {
171206 message: " JSClosure is no longer a subclass of JSFunction. Use .object(closure) instead. "
172207 )
173208 public static func function( _ closure: JSClosure ) -> JSValue {
174- . object( closure)
209+ . init ( storage : . object( closure) )
175210 }
176211
177212 @available ( * , deprecated, renamed: " object " , message: " Use .object(function) instead " )
178- public static func function( _ function: JSObject ) -> JSValue { . object( function) }
213+ public static func function( _ function: JSObject ) -> JSValue { . init ( storage : . object( function) ) }
179214}
180215
181216extension JSValue : ExpressibleByStringLiteral {
182217 public init ( stringLiteral value: String ) {
183- self = . string( JSString ( value) )
218+ self = . init ( storage : . string( JSString ( value) ) )
184219 }
185220}
186221
187222extension JSValue : ExpressibleByIntegerLiteral {
188223 public init ( integerLiteral value: Int32 ) {
189- self = . number( Double ( value) )
224+ self = . init ( storage : . number( Double ( value) ) )
190225 }
191226}
192227
193228extension JSValue : ExpressibleByFloatLiteral {
194229 public init ( floatLiteral value: Double ) {
195- self = . number( value)
230+ self = . init ( storage : . number( value) )
196231 }
197232}
198233
199234extension JSValue : ExpressibleByNilLiteral {
200235 public init ( nilLiteral _: ( ) ) {
201- self = . null
236+ self = . init ( storage : . null)
202237 }
203238}
204239
@@ -268,7 +303,7 @@ extension JSValue {
268303 /// - Parameter constructor: The constructor function to check.
269304 /// - Returns: The result of `instanceof` in the JavaScript environment.
270305 public func isInstanceOf( _ constructor: JSObject ) -> Bool {
271- switch self {
306+ switch storage {
272307 case . boolean, . string, . number, . null, . undefined, . symbol, . bigInt:
273308 return false
274309 case . object( let ref) :
0 commit comments