Skip to content

Commit

Permalink
wip add some decoding methods (where were these meant to be? earlier …
Browse files Browse the repository at this point in the history
…on i suppose)
  • Loading branch information
lawrence-forooghian committed Dec 16, 2024
1 parent 6fc93a9 commit ec350e4
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 2 deletions.
4 changes: 2 additions & 2 deletions Sources/AblyChat/DefaultMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ 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 = data["metadata"]?.objectValue {
let metadata: Metadata? = if let metadataJSONObject = try data.optionalObjectValueForKey("metadata") {
try metadataJSONObject.mapValues { try MetadataValue(jsonValue: $0) }
} else {
nil
}
let headers: Headers? = if let headersJSONObject = extras["headers"]?.objectValue {
let headers: Headers? = if let headersJSONObject = try extras.optionalObjectValueForKey("headers") {
try headersJSONObject.mapValues { try HeadersValue(jsonValue: $0) }
} else {
nil
Expand Down
3 changes: 3 additions & 0 deletions Sources/AblyChat/JSONCodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ internal protocol JSONObjectDecodable: JSONDecodable {

internal enum JSONValueDecodingError: Error {
case valueIsNotObject
case noValueForKey(String)
// TODO: inform which
case wrongTypeForKey(String)
}

// Default implementation of `JSONDecodable` conformance for `JSONObjectDecodable`
Expand Down
147 changes: 147 additions & 0 deletions Sources/AblyChat/JSONValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,150 @@ internal extension [String: JSONValue] {
mapValues(\.toAblyCocoaData)
}
}

// MARK: - Extracting values from a dictionary

// TODO: this is really a helper for JSONDecodable, put there
// TODO: Update comments

internal extension [String: JSONValue] {
func nonOptionalObjectValueForKey(_ key: String) throws -> [String: JSONValue] {
guard let value = self[key] else {
throw JSONValueDecodingError.noValueForKey(key)
}

guard case let .object(objectValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return objectValue
}

func optionalObjectValueForKey(_ key: String) throws -> [String: JSONValue]? {
guard let value = self[key] else {
return nil
}

if case .null = value {
return nil
}

guard case let .object(objectValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return objectValue
}

func arrayValueForKey(_ key: String) throws -> [JSONValue] {
guard let value = self[key] else {
throw JSONValueDecodingError.noValueForKey(key)
}

guard case let .array(arrayValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return arrayValue
}

func optionalArrayValueForKey(_ key: String) throws -> [JSONValue]? {
guard let value = self[key] else {
return nil
}

if case .null = value {
return nil
}

guard case let .array(arrayValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return arrayValue
}

func stringValueForKey(_ key: String) throws -> String {
guard let value = self[key] else {
throw JSONValueDecodingError.noValueForKey(key)
}

guard case let .string(stringValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return stringValue
}

func optionalStringValueForKey(_ key: String) throws -> String? {
guard let value = self[key] else {
return nil
}

if case .null = value {
return nil
}

guard case let .string(stringValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return stringValue
}

func numberValueForKey(_ key: String) throws -> Double {
guard let value = self[key] else {
throw JSONValueDecodingError.noValueForKey(key)
}

guard case let .number(numberValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return numberValue
}

func optionalNumberValueForKey(_ key: String) throws -> Double? {
guard let value = self[key] else {
return nil
}

if case .null = value {
return nil
}

guard case let .number(numberValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return numberValue
}

func boolValueForKey(_ key: String) throws -> Bool {
guard let value = self[key] else {
throw JSONValueDecodingError.noValueForKey(key)
}

guard case let .bool(boolValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return boolValue
}

func optionalBoolValueForKey(_ key: String) throws -> Bool? {
guard let value = self[key] else {
return nil
}

if case .null = value {
return nil
}

guard case let .bool(boolValue) = value else {
throw JSONValueDecodingError.wrongTypeForKey(key)
}

return boolValue
}
}

0 comments on commit ec350e4

Please sign in to comment.