damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

AnyCodable.swift (4833B)


      1 import Foundation
      2 /**
      3  A type-erased `Codable` value.
      4 
      5  The `AnyCodable` type forwards encoding and decoding responsibilities
      6  to an underlying value, hiding its specific underlying type.
      7 
      8  You can encode or decode mixed-type values in dictionaries
      9  and other collections that require `Encodable` or `Decodable` conformance
     10  by declaring their contained type to be `AnyCodable`.
     11 
     12  - SeeAlso: `AnyEncodable`
     13  - SeeAlso: `AnyDecodable`
     14  */
     15 @frozen public struct AnyCodable: Codable {
     16     public let value: Any
     17 
     18     public init<T>(_ value: T?) {
     19         self.value = value ?? ()
     20     }
     21 }
     22 
     23 extension AnyCodable: _AnyEncodable, _AnyDecodable {}
     24 
     25 extension AnyCodable: Equatable {
     26     public static func == (lhs: AnyCodable, rhs: AnyCodable) -> Bool {
     27         switch (lhs.value, rhs.value) {
     28         case is (Void, Void):
     29             return true
     30         case let (lhs as Bool, rhs as Bool):
     31             return lhs == rhs
     32         case let (lhs as Int, rhs as Int):
     33             return lhs == rhs
     34         case let (lhs as Int8, rhs as Int8):
     35             return lhs == rhs
     36         case let (lhs as Int16, rhs as Int16):
     37             return lhs == rhs
     38         case let (lhs as Int32, rhs as Int32):
     39             return lhs == rhs
     40         case let (lhs as Int64, rhs as Int64):
     41             return lhs == rhs
     42         case let (lhs as UInt, rhs as UInt):
     43             return lhs == rhs
     44         case let (lhs as UInt8, rhs as UInt8):
     45             return lhs == rhs
     46         case let (lhs as UInt16, rhs as UInt16):
     47             return lhs == rhs
     48         case let (lhs as UInt32, rhs as UInt32):
     49             return lhs == rhs
     50         case let (lhs as UInt64, rhs as UInt64):
     51             return lhs == rhs
     52         case let (lhs as Float, rhs as Float):
     53             return lhs == rhs
     54         case let (lhs as Double, rhs as Double):
     55             return lhs == rhs
     56         case let (lhs as String, rhs as String):
     57             return lhs == rhs
     58         case let (lhs as [String: AnyCodable], rhs as [String: AnyCodable]):
     59             return lhs == rhs
     60         case let (lhs as [AnyCodable], rhs as [AnyCodable]):
     61             return lhs == rhs
     62         case let (lhs as [String: Any], rhs as [String: Any]):
     63             return NSDictionary(dictionary: lhs) == NSDictionary(dictionary: rhs)
     64         case let (lhs as [Any], rhs as [Any]):
     65             return NSArray(array: lhs) == NSArray(array: rhs)
     66         case is (NSNull, NSNull):
     67             return true
     68         default:
     69             return false
     70         }
     71     }
     72 }
     73 
     74 extension AnyCodable: CustomStringConvertible {
     75     public var description: String {
     76         switch value {
     77         case is Void:
     78             return String(describing: nil as Any?)
     79         case let value as CustomStringConvertible:
     80             return value.description
     81         default:
     82             return String(describing: value)
     83         }
     84     }
     85 }
     86 
     87 extension AnyCodable: CustomDebugStringConvertible {
     88     public var debugDescription: String {
     89         switch value {
     90         case let value as CustomDebugStringConvertible:
     91             return "AnyCodable(\(value.debugDescription))"
     92         default:
     93             return "AnyCodable(\(description))"
     94         }
     95     }
     96 }
     97 
     98 extension AnyCodable: ExpressibleByNilLiteral {}
     99 extension AnyCodable: ExpressibleByBooleanLiteral {}
    100 extension AnyCodable: ExpressibleByIntegerLiteral {}
    101 extension AnyCodable: ExpressibleByFloatLiteral {}
    102 extension AnyCodable: ExpressibleByStringLiteral {}
    103 extension AnyCodable: ExpressibleByStringInterpolation {}
    104 extension AnyCodable: ExpressibleByArrayLiteral {}
    105 extension AnyCodable: ExpressibleByDictionaryLiteral {}
    106 
    107 
    108 extension AnyCodable: Hashable {
    109     public func hash(into hasher: inout Hasher) {
    110         switch value {
    111         case let value as Bool:
    112             hasher.combine(value)
    113         case let value as Int:
    114             hasher.combine(value)
    115         case let value as Int8:
    116             hasher.combine(value)
    117         case let value as Int16:
    118             hasher.combine(value)
    119         case let value as Int32:
    120             hasher.combine(value)
    121         case let value as Int64:
    122             hasher.combine(value)
    123         case let value as UInt:
    124             hasher.combine(value)
    125         case let value as UInt8:
    126             hasher.combine(value)
    127         case let value as UInt16:
    128             hasher.combine(value)
    129         case let value as UInt32:
    130             hasher.combine(value)
    131         case let value as UInt64:
    132             hasher.combine(value)
    133         case let value as Float:
    134             hasher.combine(value)
    135         case let value as Double:
    136             hasher.combine(value)
    137         case let value as String:
    138             hasher.combine(value)
    139         case let value as [String: AnyCodable]:
    140             hasher.combine(value)
    141         case let value as [AnyCodable]:
    142             hasher.combine(value)
    143         default:
    144             break
    145         }
    146     }
    147 }