Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -887,31 +887,31 @@ internal final class InternalDefaultLiveMap: Sendable {

// RTLM5d2b: If ObjectsMapEntry.data.boolean exists, return it
if let boolean = entry.data?.boolean {
return .primitive(.bool(boolean))
return .bool(boolean)
}

// RTLM5d2c: If ObjectsMapEntry.data.bytes exists, return it
if let bytes = entry.data?.bytes {
return .primitive(.data(bytes))
return .data(bytes)
}

// RTLM5d2d: If ObjectsMapEntry.data.number exists, return it
if let number = entry.data?.number {
return .primitive(.number(number.doubleValue))
return .number(number.doubleValue)
}

// RTLM5d2e: If ObjectsMapEntry.data.string exists, return it
if let string = entry.data?.string {
return .primitive(.string(string))
return .string(string)
}

// TODO: Needs specification (see https://github.com/ably/ably-cocoa-liveobjects-plugin/issues/46)
if let json = entry.data?.json {
switch json {
case let .array(array):
return .primitive(.jsonArray(array))
return .jsonArray(array)
case let .object(object):
return .primitive(.jsonObject(object))
return .jsonObject(object)
}
}

Expand Down
132 changes: 79 additions & 53 deletions Sources/AblyLiveObjects/Internal/InternalLiveMapValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import Foundation

/// Same as the public ``LiveMapValue`` type but with associated values of internal type.
internal enum InternalLiveMapValue: Sendable, Equatable {
case primitive(PrimitiveObjectValue)
case string(String)
case number(Double)
case bool(Bool)
case data(Data)
case jsonArray([JSONValue])
case jsonObject([String: JSONValue])
case liveMap(InternalDefaultLiveMap)
case liveCounter(InternalDefaultLiveCounter)

Expand All @@ -13,8 +18,18 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
/// Needed in order to access the internals of user-provided LiveObject-valued LiveMap entries to extract their object ID.
internal init(liveMapValue: LiveMapValue) {
switch liveMapValue {
case let .primitive(primitiveValue):
self = .primitive(primitiveValue)
case let .string(value):
self = .string(value)
case let .number(value):
self = .number(value)
case let .bool(value):
self = .bool(value)
case let .data(value):
self = .data(value)
case let .jsonArray(value):
self = .jsonArray(value)
case let .jsonObject(value):
self = .jsonObject(value)
case let .liveMap(publicLiveMap):
guard let publicDefaultLiveMap = publicLiveMap as? PublicDefaultLiveMap else {
// TODO: Try and remove this runtime check and know this type statically, see https://github.com/ably/ably-cocoa-liveobjects-plugin/issues/37
Expand All @@ -36,21 +51,18 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
internal var toObjectData: ObjectData {
// RTO11f4c1: Create an ObjectsMapEntry for the current value
switch self {
case let .primitive(primitiveValue):
switch primitiveValue {
case let .bool(value):
.init(boolean: value)
case let .data(value):
.init(bytes: value)
case let .number(value):
.init(number: NSNumber(value: value))
case let .string(value):
.init(string: value)
case let .jsonArray(value):
.init(json: .array(value))
case let .jsonObject(value):
.init(json: .object(value))
}
case let .bool(value):
.init(boolean: value)
case let .data(value):
.init(bytes: value)
case let .number(value):
.init(number: NSNumber(value: value))
case let .string(value):
.init(string: value)
case let .jsonArray(value):
.init(json: .array(value))
case let .jsonObject(value):
.init(json: .object(value))
case let .liveMap(liveMap):
// RTO11f4c1a: If the value is of type LiveMap, set ObjectsMapEntry.data.objectId to the objectId of that object
.init(objectId: liveMap.objectID)
Expand All @@ -62,14 +74,6 @@ internal enum InternalLiveMapValue: Sendable, Equatable {

// MARK: - Convenience getters for associated values

/// If this `InternalLiveMapValue` has case `primitive`, this returns the associated value. Else, it returns `nil`.
internal var primitiveValue: PrimitiveObjectValue? {
if case let .primitive(value) = self {
return value
}
return nil
}

/// If this `InternalLiveMapValue` has case `liveMap`, this returns the associated value. Else, it returns `nil`.
internal var liveMapValue: InternalDefaultLiveMap? {
if case let .liveMap(value) = self {
Expand All @@ -86,54 +90,76 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
return nil
}

/// If this `InternalLiveMapValue` has case `primitive` with a string value, this returns that value. Else, it returns `nil`.
/// If this `InternalLiveMapValue` has case `string`, this returns that value. Else, it returns `nil`.
internal var stringValue: String? {
primitiveValue?.stringValue
if case let .string(value) = self {
return value
}
return nil
}

/// If this `InternalLiveMapValue` has case `primitive` with a number value, this returns that value. Else, it returns `nil`.
/// If this `InternalLiveMapValue` has case `number`, this returns that value. Else, it returns `nil`.
internal var numberValue: Double? {
primitiveValue?.numberValue
if case let .number(value) = self {
return value
}
return nil
}

/// If this `InternalLiveMapValue` has case `primitive` with a boolean value, this returns that value. Else, it returns `nil`.
/// If this `InternalLiveMapValue` has case `bool`, this returns that value. Else, it returns `nil`.
internal var boolValue: Bool? {
primitiveValue?.boolValue
if case let .bool(value) = self {
return value
}
return nil
}

/// If this `InternalLiveMapValue` has case `primitive` with a data value, this returns that value. Else, it returns `nil`.
/// If this `InternalLiveMapValue` has case `data`, this returns that value. Else, it returns `nil`.
internal var dataValue: Data? {
primitiveValue?.dataValue
if case let .data(value) = self {
return value
}
return nil
}

/// If this `InternalLiveMapValue` has case `primitive` with a JSON array value, this returns that value. Else, it returns `nil`.
/// If this `InternalLiveMapValue` has case `jsonArray`, this returns that value. Else, it returns `nil`.
internal var jsonArrayValue: [JSONValue]? {
primitiveValue?.jsonArrayValue
if case let .jsonArray(value) = self {
return value
}
return nil
}

/// If this `InternalLiveMapValue` has case `primitive` with a JSON object value, this returns that value. Else, it returns `nil`.
/// If this `InternalLiveMapValue` has case `jsonObject`, this returns that value. Else, it returns `nil`.
internal var jsonObjectValue: [String: JSONValue]? {
primitiveValue?.jsonObjectValue
if case let .jsonObject(value) = self {
return value
}
return nil
}

// MARK: - Equatable Implementation

internal static func == (lhs: InternalLiveMapValue, rhs: InternalLiveMapValue) -> Bool {
switch lhs {
case let .primitive(lhsValue):
if case let .primitive(rhsValue) = rhs, lhsValue == rhsValue {
return true
}
case let .liveMap(lhsMap):
if case let .liveMap(rhsMap) = rhs, lhsMap === rhsMap {
return true
}
case let .liveCounter(lhsCounter):
if case let .liveCounter(rhsCounter) = rhs, lhsCounter === rhsCounter {
return true
}
switch (lhs, rhs) {
case let (.string(lhsValue), .string(rhsValue)):
lhsValue == rhsValue
case let (.number(lhsValue), .number(rhsValue)):
lhsValue == rhsValue
case let (.bool(lhsValue), .bool(rhsValue)):
lhsValue == rhsValue
case let (.data(lhsValue), .data(rhsValue)):
lhsValue == rhsValue
case let (.jsonArray(lhsValue), .jsonArray(rhsValue)):
lhsValue == rhsValue
case let (.jsonObject(lhsValue), .jsonObject(rhsValue)):
lhsValue == rhsValue
case let (.liveMap(lhsMap), .liveMap(rhsMap)):
lhsMap === rhsMap
case let (.liveCounter(lhsCounter), .liveCounter(rhsCounter)):
lhsCounter === rhsCounter
default:
false
}

return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,18 @@ internal extension InternalLiveMapValue {
/// Fetches the cached public object that wraps this `InternalLiveMapValue`'s associated value, creating a new public object if there isn't already one.
func toPublic(creationArgs: PublicValueCreationArgs) -> LiveMapValue {
switch self {
case let .primitive(primitive):
.primitive(primitive)
case let .string(value):
.string(value)
case let .number(value):
.number(value)
case let .bool(value):
.bool(value)
case let .data(value):
.data(value)
case let .jsonArray(value):
.jsonArray(value)
case let .jsonObject(value):
.jsonObject(value)
case let .liveMap(internalLiveMap):
.liveMap(
PublicObjectsStore.shared.getOrCreateMap(
Expand Down
Loading