Skip to content

Commit

Permalink
Allow JSBridgedType (but not JSBridgedClass) to hold non-objects
Browse files Browse the repository at this point in the history
  • Loading branch information
j-f1 committed Sep 15, 2020
1 parent b50a00f commit ed9e4b7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 24 deletions.
34 changes: 10 additions & 24 deletions Sources/JavaScriptKit/JSBridgedType.swift
Original file line number Diff line number Diff line change
@@ -1,45 +1,31 @@
// Use this protocol when your type has no single JavaScript class.
// For example, a union type of multiple classes.
public protocol JSBridgedType: JSValueCodable, CustomStringConvertible {
var objectRef: JSObject { get }
init?(objectRef: JSObject)
var value: JSValue { get }
init?(from value: JSValue)
}

extension JSBridgedType {
public static func construct(from value: JSValue) -> Self? {
guard let object = value.object else { return nil }
return Self.init(objectRef: object)
return Self.init(from: value)
}

public func jsValue() -> JSValue {
.object(objectRef)
}
public func jsValue() -> JSValue { value }

public var description: String {
return objectRef.toString!().fromJSValue()!
}
public var description: String { value.description }
}


public protocol JSBridgedClass: JSBridgedType {
static var classRef: JSFunction { get }
var objectRef: JSObject { get }
init(withCompatibleObject objectRef: JSObject)
}

extension JSBridgedClass {
public init?(objectRef: JSObject) {
guard objectRef.isInstanceOf(Self.classRef) else { return nil }
self.init(withCompatibleObject: objectRef)
}
}

public func staticCast<Type: JSBridgedType>(_ ref: JSBridgedType) -> Type? {
return Type(objectRef: ref.objectRef)
}

public func dynamicCast<Type: JSBridgedClass>(_ ref: JSBridgedClass) -> Type? {
guard ref.objectRef.isInstanceOf(Type.classRef) else {
return nil
public var value: JSValue { objectRef.jsValue() }
public init?(from value: JSValue) {
guard let object = value.object, object.isInstanceOf(Self.classRef) else { return nil }
self.init(withCompatibleObject: object)
}
return staticCast(ref)
}
19 changes: 19 additions & 0 deletions Sources/JavaScriptKit/JSValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,22 @@ extension JSValue {
}
}
}

extension JSValue: CustomStringConvertible {
public var description: String {
switch self {
case let .boolean(boolean):
return boolean.description
case .string(let string):
return string
case .number(let number):
return number.description
case .object(let object), .function(let object as JSObject):
return object.toString!().fromJSValue()!
case .null:
return "null"
case .undefined:
return "undefined"
}
}
}
11 changes: 11 additions & 0 deletions Sources/JavaScriptKit/Support.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,14 @@ public struct AnyJSValueCodable: JSValueCodable, ExpressibleByNilLiteral {
self.jsValue().fromJSValue()
}
}

public func staticCast<Type: JSBridgedType>(_ ref: JSBridgedType) -> Type? {
return Type(from: ref.value)
}

public func dynamicCast<Type: JSBridgedClass>(_ ref: JSBridgedClass) -> Type? {
guard ref.objectRef.isInstanceOf(Type.classRef) else {
return nil
}
return staticCast(ref)
}

0 comments on commit ed9e4b7

Please sign in to comment.