Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECO-4927] Change Metadata to use JSONValue #202

Merged
merged 1 commit into from
Dec 18, 2024
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ try await room.reactions.send(params: .init(type: "like"))
You can also add any metadata and headers to reactions:

```swift
try await room.reactions.send(params: .init(type: "🎉", metadata: ["effect": .string("fireworks")]))
try await room.reactions.send(params: .init(type: "🎉", metadata: ["effect": "fireworks"]))
```

### Subscribing to room reactions
Expand Down
2 changes: 1 addition & 1 deletion Sources/AblyChat/ChatAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal final class ChatAPI: Sendable {

// (CHA-M3b) A message may be sent without metadata or headers. When these are not specified by the user, they must be omitted from the REST payload.
if let metadata = params.metadata {
body["metadata"] = .object(metadata.mapValues(\.toJSONValue))
body["metadata"] = .object(metadata)
}

if let headers = params.headers {
Expand Down
7 changes: 2 additions & 5 deletions Sources/AblyChat/DefaultMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,8 @@ internal final class DefaultMessages: Messages, EmitsDiscontinuities {
throw ARTErrorInfo.create(withCode: 50000, status: 500, message: "Received incoming message without clientId")
}

let metadata: Metadata? = if let metadataJSONObject = try data.optionalObjectValueForKey("metadata") {
try metadataJSONObject.mapValues { try MetadataValue(jsonValue: $0) }
} else {
nil
}
let metadata = try data.optionalObjectValueForKey("metadata")

let headers: Headers? = if let headersJSONObject = try extras.optionalObjectValueForKey("headers") {
try headersJSONObject.mapValues { try HeadersValue(jsonValue: $0) }
} else {
Expand Down
2 changes: 1 addition & 1 deletion Sources/AblyChat/Message.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ extension Message: JSONObjectDecodable {
roomID: jsonObject.stringValueForKey("roomId"),
text: jsonObject.stringValueForKey("text"),
createdAt: jsonObject.optionalAblyProtocolDateValueForKey("createdAt"),
metadata: jsonObject.objectValueForKey("metadata").mapValues { try .init(jsonValue: $0) },
metadata: jsonObject.objectValueForKey("metadata"),
headers: jsonObject.objectValueForKey("headers").mapValues { try .init(jsonValue: $0) }
)
}
Expand Down
47 changes: 1 addition & 46 deletions Sources/AblyChat/Metadata.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
// TODO: https://github.com/ably-labs/ably-chat-swift/issues/13 - try to improve this type

public enum MetadataValue: Sendable, Equatable {
case string(String)
case number(Double)
case bool(Bool)
case null
}

/**
* Metadata is a map of extra information that can be attached to chat
* messages. It is not used by Ably and is sent as part of the realtime
Expand All @@ -17,40 +8,4 @@ public enum MetadataValue: Sendable, Equatable {
* Do not use metadata for authoritative information. There is no server-side
* validation. When reading the metadata treat it like user input.
*/
public typealias Metadata = [String: MetadataValue]

extension MetadataValue: JSONDecodable {
internal enum JSONDecodingError: Error {
case unsupportedJSONValue(JSONValue)
}

internal init(jsonValue: JSONValue) throws {
self = switch jsonValue {
case let .string(value):
.string(value)
case let .number(value):
.number(value)
case let .bool(value):
.bool(value)
case .null:
.null
default:
throw JSONDecodingError.unsupportedJSONValue(jsonValue)
}
}
}

extension MetadataValue: JSONEncodable {
internal var toJSONValue: JSONValue {
switch self {
case let .string(value):
.string(value)
case let .number(value):
.number(Double(value))
case let .bool(value):
.bool(value)
case .null:
.null
}
}
}
public typealias Metadata = [String: JSONValue]
4 changes: 2 additions & 2 deletions Sources/AblyChat/RoomReactionDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ extension RoomReactionDTO.Data: JSONObjectCodable {

internal init(jsonObject: [String: JSONValue]) throws {
type = try jsonObject.stringValueForKey(JSONKey.type.rawValue)
metadata = try jsonObject.optionalObjectValueForKey(JSONKey.metadata.rawValue)?.mapValues { try .init(jsonValue: $0) }
metadata = try jsonObject.optionalObjectValueForKey(JSONKey.metadata.rawValue)
}

internal var toJSONObject: [String: JSONValue] {
[
JSONKey.type.rawValue: .string(type),
JSONKey.metadata.rawValue: .object(metadata?.mapValues(\.toJSONValue) ?? [:]),
JSONKey.metadata.rawValue: .object(metadata ?? [:]),
]
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/AblyChatTests/ChatAPITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ struct ChatAPITests {
params: .init(
text: "", // arbitrary
// The exact value here is arbitrary, just want to check it gets serialized
metadata: ["numberKey": .number(10), "stringKey": .string("hello")]
metadata: ["numberKey": 10, "stringKey": "hello"]
maratal marked this conversation as resolved.
Show resolved Hide resolved
)
)

Expand Down
2 changes: 1 addition & 1 deletion Tests/AblyChatTests/DefaultRoomReactionsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct DefaultRoomReactionsTests {

let sendReactionParams = SendReactionParams(
type: "like",
metadata: ["someMetadataKey": MetadataValue.string("someMetadataValue")],
metadata: ["someMetadataKey": "someMetadataValue"],
headers: ["someHeadersKey": HeadersValue.string("someHeadersValue")]
)

Expand Down
4 changes: 2 additions & 2 deletions Tests/AblyChatTests/IntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ struct IntegrationTests {
let txMessageAfterRxSubscribe = try await txRoom.messages.send(
params: .init(
text: "Hello from txRoom, after rxRoom subscribe",
metadata: ["someMetadataKey": .number(123), "someOtherMetadataKey": .string("foo")],
metadata: ["someMetadataKey": 123, "someOtherMetadataKey": "foo"],
headers: ["someHeadersKey": .number(456), "someOtherHeadersKey": .string("bar")]
)
)
Expand Down Expand Up @@ -168,7 +168,7 @@ struct IntegrationTests {
try await txRoom.reactions.send(
params: .init(
type: "heart",
metadata: ["someMetadataKey": .number(123), "someOtherMetadataKey": .string("foo")],
metadata: ["someMetadataKey": 123, "someOtherMetadataKey": "foo"],
headers: ["someHeadersKey": .number(456), "someOtherHeadersKey": .string("bar")]
)
)
Expand Down
4 changes: 2 additions & 2 deletions Tests/AblyChatTests/RoomReactionDTOTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ enum RoomReactionDTOTests {
]
)

#expect(data == .init(type: "someType", metadata: ["someStringKey": .string("someStringValue"), "someNumberKey": .number(123)]))
#expect(data == .init(type: "someType", metadata: ["someStringKey": "someStringValue", "someNumberKey": 123]))
}

// MARK: - JSONCodable
Expand All @@ -49,7 +49,7 @@ enum RoomReactionDTOTests {

@Test
func toJSONValue() {
let data = RoomReactionDTO.Data(type: "someType", metadata: ["someStringKey": .string("someStringValue"), "someNumberKey": .number(123)])
let data = RoomReactionDTO.Data(type: "someType", metadata: ["someStringKey": "someStringValue", "someNumberKey": 123])

#expect(data.toJSONValue == [
"type": "someType",
Expand Down
Loading