Skip to content

Commit 19ba2e9

Browse files
Merge pull request #66 from ably/65-LiveMapValue-improvements
[ECO-5525] Improve `LiveMapValue` API
2 parents 8fcd4a2 + 714988d commit 19ba2e9

9 files changed

Lines changed: 268 additions & 204 deletions

File tree

Sources/AblyLiveObjects/Internal/InternalDefaultLiveMap.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -887,31 +887,31 @@ internal final class InternalDefaultLiveMap: Sendable {
887887

888888
// RTLM5d2b: If ObjectsMapEntry.data.boolean exists, return it
889889
if let boolean = entry.data?.boolean {
890-
return .primitive(.bool(boolean))
890+
return .bool(boolean)
891891
}
892892

893893
// RTLM5d2c: If ObjectsMapEntry.data.bytes exists, return it
894894
if let bytes = entry.data?.bytes {
895-
return .primitive(.data(bytes))
895+
return .data(bytes)
896896
}
897897

898898
// RTLM5d2d: If ObjectsMapEntry.data.number exists, return it
899899
if let number = entry.data?.number {
900-
return .primitive(.number(number.doubleValue))
900+
return .number(number.doubleValue)
901901
}
902902

903903
// RTLM5d2e: If ObjectsMapEntry.data.string exists, return it
904904
if let string = entry.data?.string {
905-
return .primitive(.string(string))
905+
return .string(string)
906906
}
907907

908908
// TODO: Needs specification (see https://github.com/ably/ably-cocoa-liveobjects-plugin/issues/46)
909909
if let json = entry.data?.json {
910910
switch json {
911911
case let .array(array):
912-
return .primitive(.jsonArray(array))
912+
return .jsonArray(array)
913913
case let .object(object):
914-
return .primitive(.jsonObject(object))
914+
return .jsonObject(object)
915915
}
916916
}
917917

Sources/AblyLiveObjects/Internal/InternalLiveMapValue.swift

Lines changed: 79 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import Foundation
22

33
/// Same as the public ``LiveMapValue`` type but with associated values of internal type.
44
internal enum InternalLiveMapValue: Sendable, Equatable {
5-
case primitive(PrimitiveObjectValue)
5+
case string(String)
6+
case number(Double)
7+
case bool(Bool)
8+
case data(Data)
9+
case jsonArray([JSONValue])
10+
case jsonObject([String: JSONValue])
611
case liveMap(InternalDefaultLiveMap)
712
case liveCounter(InternalDefaultLiveCounter)
813

@@ -13,8 +18,18 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
1318
/// Needed in order to access the internals of user-provided LiveObject-valued LiveMap entries to extract their object ID.
1419
internal init(liveMapValue: LiveMapValue) {
1520
switch liveMapValue {
16-
case let .primitive(primitiveValue):
17-
self = .primitive(primitiveValue)
21+
case let .string(value):
22+
self = .string(value)
23+
case let .number(value):
24+
self = .number(value)
25+
case let .bool(value):
26+
self = .bool(value)
27+
case let .data(value):
28+
self = .data(value)
29+
case let .jsonArray(value):
30+
self = .jsonArray(value)
31+
case let .jsonObject(value):
32+
self = .jsonObject(value)
1833
case let .liveMap(publicLiveMap):
1934
guard let publicDefaultLiveMap = publicLiveMap as? PublicDefaultLiveMap else {
2035
// TODO: Try and remove this runtime check and know this type statically, see https://github.com/ably/ably-cocoa-liveobjects-plugin/issues/37
@@ -36,21 +51,18 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
3651
internal var toObjectData: ObjectData {
3752
// RTO11f4c1: Create an ObjectsMapEntry for the current value
3853
switch self {
39-
case let .primitive(primitiveValue):
40-
switch primitiveValue {
41-
case let .bool(value):
42-
.init(boolean: value)
43-
case let .data(value):
44-
.init(bytes: value)
45-
case let .number(value):
46-
.init(number: NSNumber(value: value))
47-
case let .string(value):
48-
.init(string: value)
49-
case let .jsonArray(value):
50-
.init(json: .array(value))
51-
case let .jsonObject(value):
52-
.init(json: .object(value))
53-
}
54+
case let .bool(value):
55+
.init(boolean: value)
56+
case let .data(value):
57+
.init(bytes: value)
58+
case let .number(value):
59+
.init(number: NSNumber(value: value))
60+
case let .string(value):
61+
.init(string: value)
62+
case let .jsonArray(value):
63+
.init(json: .array(value))
64+
case let .jsonObject(value):
65+
.init(json: .object(value))
5466
case let .liveMap(liveMap):
5567
// RTO11f4c1a: If the value is of type LiveMap, set ObjectsMapEntry.data.objectId to the objectId of that object
5668
.init(objectId: liveMap.objectID)
@@ -62,14 +74,6 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
6274

6375
// MARK: - Convenience getters for associated values
6476

65-
/// If this `InternalLiveMapValue` has case `primitive`, this returns the associated value. Else, it returns `nil`.
66-
internal var primitiveValue: PrimitiveObjectValue? {
67-
if case let .primitive(value) = self {
68-
return value
69-
}
70-
return nil
71-
}
72-
7377
/// If this `InternalLiveMapValue` has case `liveMap`, this returns the associated value. Else, it returns `nil`.
7478
internal var liveMapValue: InternalDefaultLiveMap? {
7579
if case let .liveMap(value) = self {
@@ -86,54 +90,76 @@ internal enum InternalLiveMapValue: Sendable, Equatable {
8690
return nil
8791
}
8892

89-
/// If this `InternalLiveMapValue` has case `primitive` with a string value, this returns that value. Else, it returns `nil`.
93+
/// If this `InternalLiveMapValue` has case `string`, this returns that value. Else, it returns `nil`.
9094
internal var stringValue: String? {
91-
primitiveValue?.stringValue
95+
if case let .string(value) = self {
96+
return value
97+
}
98+
return nil
9299
}
93100

94-
/// If this `InternalLiveMapValue` has case `primitive` with a number value, this returns that value. Else, it returns `nil`.
101+
/// If this `InternalLiveMapValue` has case `number`, this returns that value. Else, it returns `nil`.
95102
internal var numberValue: Double? {
96-
primitiveValue?.numberValue
103+
if case let .number(value) = self {
104+
return value
105+
}
106+
return nil
97107
}
98108

99-
/// If this `InternalLiveMapValue` has case `primitive` with a boolean value, this returns that value. Else, it returns `nil`.
109+
/// If this `InternalLiveMapValue` has case `bool`, this returns that value. Else, it returns `nil`.
100110
internal var boolValue: Bool? {
101-
primitiveValue?.boolValue
111+
if case let .bool(value) = self {
112+
return value
113+
}
114+
return nil
102115
}
103116

104-
/// If this `InternalLiveMapValue` has case `primitive` with a data value, this returns that value. Else, it returns `nil`.
117+
/// If this `InternalLiveMapValue` has case `data`, this returns that value. Else, it returns `nil`.
105118
internal var dataValue: Data? {
106-
primitiveValue?.dataValue
119+
if case let .data(value) = self {
120+
return value
121+
}
122+
return nil
107123
}
108124

109-
/// If this `InternalLiveMapValue` has case `primitive` with a JSON array value, this returns that value. Else, it returns `nil`.
125+
/// If this `InternalLiveMapValue` has case `jsonArray`, this returns that value. Else, it returns `nil`.
110126
internal var jsonArrayValue: [JSONValue]? {
111-
primitiveValue?.jsonArrayValue
127+
if case let .jsonArray(value) = self {
128+
return value
129+
}
130+
return nil
112131
}
113132

114-
/// If this `InternalLiveMapValue` has case `primitive` with a JSON object value, this returns that value. Else, it returns `nil`.
133+
/// If this `InternalLiveMapValue` has case `jsonObject`, this returns that value. Else, it returns `nil`.
115134
internal var jsonObjectValue: [String: JSONValue]? {
116-
primitiveValue?.jsonObjectValue
135+
if case let .jsonObject(value) = self {
136+
return value
137+
}
138+
return nil
117139
}
118140

119141
// MARK: - Equatable Implementation
120142

121143
internal static func == (lhs: InternalLiveMapValue, rhs: InternalLiveMapValue) -> Bool {
122-
switch lhs {
123-
case let .primitive(lhsValue):
124-
if case let .primitive(rhsValue) = rhs, lhsValue == rhsValue {
125-
return true
126-
}
127-
case let .liveMap(lhsMap):
128-
if case let .liveMap(rhsMap) = rhs, lhsMap === rhsMap {
129-
return true
130-
}
131-
case let .liveCounter(lhsCounter):
132-
if case let .liveCounter(rhsCounter) = rhs, lhsCounter === rhsCounter {
133-
return true
134-
}
144+
switch (lhs, rhs) {
145+
case let (.string(lhsValue), .string(rhsValue)):
146+
lhsValue == rhsValue
147+
case let (.number(lhsValue), .number(rhsValue)):
148+
lhsValue == rhsValue
149+
case let (.bool(lhsValue), .bool(rhsValue)):
150+
lhsValue == rhsValue
151+
case let (.data(lhsValue), .data(rhsValue)):
152+
lhsValue == rhsValue
153+
case let (.jsonArray(lhsValue), .jsonArray(rhsValue)):
154+
lhsValue == rhsValue
155+
case let (.jsonObject(lhsValue), .jsonObject(rhsValue)):
156+
lhsValue == rhsValue
157+
case let (.liveMap(lhsMap), .liveMap(rhsMap)):
158+
lhsMap === rhsMap
159+
case let (.liveCounter(lhsCounter), .liveCounter(rhsCounter)):
160+
lhsCounter === rhsCounter
161+
default:
162+
false
135163
}
136-
137-
return false
138164
}
139165
}

Sources/AblyLiveObjects/Public/Public Proxy Objects/InternalLiveMapValue+ToPublic.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,18 @@ internal extension InternalLiveMapValue {
2020
/// Fetches the cached public object that wraps this `InternalLiveMapValue`'s associated value, creating a new public object if there isn't already one.
2121
func toPublic(creationArgs: PublicValueCreationArgs) -> LiveMapValue {
2222
switch self {
23-
case let .primitive(primitive):
24-
.primitive(primitive)
23+
case let .string(value):
24+
.string(value)
25+
case let .number(value):
26+
.number(value)
27+
case let .bool(value):
28+
.bool(value)
29+
case let .data(value):
30+
.data(value)
31+
case let .jsonArray(value):
32+
.jsonArray(value)
33+
case let .jsonObject(value):
34+
.jsonObject(value)
2535
case let .liveMap(internalLiveMap):
2636
.liveMap(
2737
PublicObjectsStore.shared.getOrCreateMap(

0 commit comments

Comments
 (0)