diff --git a/AnyCodable/DecodingContainer+AnyCollection.swift b/AnyCodable/DecodingContainer+AnyCollection.swift index 129a938..9c5280a 100644 --- a/AnyCodable/DecodingContainer+AnyCollection.swift +++ b/AnyCodable/DecodingContainer+AnyCollection.swift @@ -56,6 +56,11 @@ extension KeyedDecodingContainer { let values = try nestedContainer(keyedBy: AnyCodingKey.self, forKey: key) return try values.decode(type) } + + public func decode(_ type: [String: Any].Type, forKey key: KeyedDecodingContainer.Key) throws -> [String: T] { + let values = try nestedContainer(keyedBy: AnyCodingKey.self, forKey: key) + return try values.decode(type) + } /// Decodes a value of the given type for the given key, if present. /// @@ -94,6 +99,12 @@ extension KeyedDecodingContainer { try decodeNil(forKey: key) == false else { return nil } return try decode(type, forKey: key) } + + public func decodeIfPresent(_ type: [String: Any].Type, forKey key: KeyedDecodingContainer.Key) throws -> [String: T]? { + guard contains(key), + try decodeNil(forKey: key) == false else { return nil } + return try decode(type, forKey: key) + } } private extension KeyedDecodingContainer { @@ -118,6 +129,16 @@ private extension KeyedDecodingContainer { } return dictionary } + + func decode(_ type: [String: Any].Type) throws -> [String: T] { + var dictionary: [String: T] = [:] + for key in allKeys { + if let object = try? decode(T.self, forKey: key) { + dictionary[key.stringValue] = object + } + } + return dictionary + } } private extension UnkeyedDecodingContainer { @@ -145,3 +166,4 @@ private extension UnkeyedDecodingContainer { return elements } } + diff --git a/AnyCodable/EncodingContainer+AnyCollection.swift b/AnyCodable/EncodingContainer+AnyCollection.swift index b08f5bd..9d13fd6 100644 --- a/AnyCodable/EncodingContainer+AnyCollection.swift +++ b/AnyCodable/EncodingContainer+AnyCollection.swift @@ -81,6 +81,8 @@ private extension KeyedEncodingContainer where K == AnyCodingKey { try encode(dict, forKey: key) case let array as [Any]: try encode(array, forKey: key) + case let encodable as AnyEncodable: + try encode(encodable, forKey: key) default: debugPrint("⚠️ Unsuported type!", v) continue @@ -113,6 +115,8 @@ private extension UnkeyedEncodingContainer { case let array as [Any]: var values = nestedUnkeyedContainer() try values.encode(array) + case let encodable as AnyEncodable: + try encode(encodable) default: debugPrint("⚠️ Unsuported type!", v) } @@ -129,3 +133,15 @@ private extension UnkeyedEncodingContainer { try container.encode(value) } } + +public struct AnyEncodable: Encodable { + + private let _encode: (Encoder) throws -> Void + public init(_ wrapped: T) { + _encode = wrapped.encode + } + + public func encode(to encoder: Encoder) throws { + try _encode(encoder) + } +}