Skip to content

Commit

Permalink
wip separate thing for encoding to object
Browse files Browse the repository at this point in the history
simplifies parsing from object (you don't have to do the "is it an
object" check yourself) and also lets you get something that's
ARTJSONWhateverCompatible (which will be needed when we start passing as
`extras` to `publish`)

TODO move this test out to make it more general

TODO update protocol name in test?
  • Loading branch information
lawrence-forooghian committed Dec 16, 2024
1 parent ee49802 commit e195904
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 15 deletions.
32 changes: 32 additions & 0 deletions Sources/AblyChat/JSONCodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,35 @@ internal protocol JSONDecodable {
}

internal typealias JSONCodable = JSONDecodable & JSONEncodable

internal protocol JSONObjectEncodable: JSONEncodable {
var toJSONObject: [String: JSONValue] { get }
}

// Default implementation of `JSONEncodable` conformance for `JSONObjectEncodable`
internal extension JSONObjectEncodable {
var toJSONValue: JSONValue {
.object(toJSONObject)
}
}

internal protocol JSONObjectDecodable: JSONDecodable {
init(jsonObject: [String: JSONValue]) throws
}

internal enum JSONValueDecodingError: Error {
case valueIsNotObject
}

// Default implementation of `JSONDecodable` conformance for `JSONObjectDecodable`
internal extension JSONObjectDecodable {
init(jsonValue: JSONValue) throws {
guard case let .object(jsonObject) = jsonValue else {
throw JSONValueDecodingError.valueIsNotObject
}

self = try .init(jsonObject: jsonObject)
}
}

internal typealias JSONObjectCodable = JSONObjectDecodable & JSONObjectEncodable
14 changes: 13 additions & 1 deletion Sources/AblyChat/JSONValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ internal extension JSONValue {
var toAblyCocoaData: Any {
switch self {
case let .object(underlying):
underlying.mapValues(\.toAblyCocoaData)
underlying.toAblyCocoaDataDictionary
case let .array(underlying):
underlying.map(\.toAblyCocoaData)
case let .string(underlying):
Expand All @@ -183,3 +183,15 @@ internal extension JSONValue {
}
}
}

internal extension [String: JSONValue] {
/// Creates an ably-cocoa deserialized JSON object from a dictionary that has string keys and `JSONValue` values.
///
/// Specifically, the value of this property can be used as:
///
/// - `ARTPresenceMessage`’s `data` property
/// - the `data` argument that’s passed to `ARTRealtime`’s `request(…)` method
var toAblyCocoaDataDictionary: [String: Any] {
mapValues(\.toAblyCocoaData)
}
}
18 changes: 5 additions & 13 deletions Sources/AblyChat/PresenceDataDTO.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,24 @@ internal struct PresenceDataDTO: Equatable {
internal var userCustomData: PresenceData?
}

// MARK: - JSONCodable
// MARK: - JSONObjectCodable

extension PresenceDataDTO: JSONCodable {
extension PresenceDataDTO: JSONObjectCodable {
internal enum JSONKey: String {
case userCustomData
}

internal enum DecodingError: Error {
case topLevelValueHasWrongType
}

internal init(jsonValue: JSONValue) throws {
guard case let .object(jsonObject) = jsonValue else {
throw DecodingError.topLevelValueHasWrongType
}

internal init(jsonObject: [String: JSONValue]) throws {
userCustomData = jsonObject[JSONKey.userCustomData.rawValue]
}

internal var toJSONValue: JSONValue {
internal var toJSONObject: [String: JSONValue] {
var result: [String: JSONValue] = [:]

if let userCustomData {
result[JSONKey.userCustomData.rawValue] = userCustomData
}

return .object(result)
return result
}
}
2 changes: 1 addition & 1 deletion Tests/AblyChatTests/PresenceDataDTOTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct PresenceDataDTOTests {

@Test
func initWithJSONValue_failsIfNotObject() {
#expect(throws: PresenceDataDTO.DecodingError.self) {
#expect(throws: JSONValueDecodingError.self) {
try PresenceDataDTO(jsonValue: "hello")
}
}
Expand Down

0 comments on commit e195904

Please sign in to comment.