A fast, safe, and efficient CBOR serialization library for Swift on any platform. swiftpackageindex.com/thecoolwinter/CBOR/1.1.1/documentation/cbor
atproto swift cbor
at dag-cbor 194 lines 6.1 kB view raw
1// From https://github.com/Flight-School/AnyCodable/blob/master/Sources/AnyCodable/AnyDecodable.swift 2 3// swiftlint:disable cyclomatic_complexity 4// swiftlint:disable line_length 5// swiftlint:disable type_name 6 7#if canImport(FoundationEssentials) 8import FoundationEssentials 9#else 10import Foundation 11#endif 12 13/** 14 A type-erased `Decodable` value. 15 16 The `AnyDecodable` type forwards decoding responsibilities 17 to an underlying value, hiding its specific underlying type. 18 19 You can decode mixed-type values in dictionaries 20 and other collections that require `Decodable` conformance 21 by declaring their contained type to be `AnyDecodable`: 22 23 let json = """ 24 { 25 "boolean": true, 26 "integer": 42, 27 "double": 3.141592653589793, 28 "string": "string", 29 "array": [1, 2, 3], 30 "nested": { 31 "a": "alpha", 32 "b": "bravo", 33 "c": "charlie" 34 }, 35 "null": null 36 } 37 """.data(using: .utf8)! 38 39 let decoder = JSONDecoder() 40 let dictionary = try! decoder.decode([String: AnyDecodable].self, from: json) 41 */ 42struct AnyDecodable: Decodable { 43 let value: Any 44 45 init<T>(_ value: T?) { 46 self.value = value ?? () 47 } 48} 49 50@usableFromInline 51protocol _AnyDecodable { 52 var value: Any { get } 53 init<T>(_ value: T?) 54} 55 56extension AnyDecodable: _AnyDecodable {} 57 58extension _AnyDecodable { 59 init(from decoder: Decoder) throws { 60 let container = try decoder.singleValueContainer() 61 62 if container.decodeNil() { 63 self.init(Optional<Self>.none) 64 } else if let bool = try? container.decode(Bool.self) { 65 self.init(bool) 66 } else if let int = try? container.decode(Int.self) { 67 self.init(int) 68 } else if let uint = try? container.decode(UInt.self) { 69 self.init(uint) 70 } else if let double = try? container.decode(Double.self) { 71 self.init(double) 72 } else if let string = try? container.decode(String.self) { 73 self.init(string) 74 } else if let array = try? container.decode([AnyDecodable].self) { 75 self.init(array.map { $0.value }) 76 } else if let dictionary = try? container.decode([String: AnyDecodable].self) { 77 self.init(dictionary.mapValues { $0.value }) 78 } else { 79 throw DecodingError.dataCorruptedError(in: container, debugDescription: "AnyDecodable value cannot be decoded") 80 } 81 } 82} 83 84extension AnyDecodable: Equatable { 85 static func == (lhs: AnyDecodable, rhs: AnyDecodable) -> Bool { 86 switch (lhs.value, rhs.value) { 87 case (Optional<Self>.none, Optional<Self>.none), is (Void, Void): 88 return true 89 case let (lhs as Bool, rhs as Bool): 90 return lhs == rhs 91 case let (lhs as Int, rhs as Int): 92 return lhs == rhs 93 case let (lhs as Int8, rhs as Int8): 94 return lhs == rhs 95 case let (lhs as Int16, rhs as Int16): 96 return lhs == rhs 97 case let (lhs as Int32, rhs as Int32): 98 return lhs == rhs 99 case let (lhs as Int64, rhs as Int64): 100 return lhs == rhs 101 case let (lhs as UInt, rhs as UInt): 102 return lhs == rhs 103 case let (lhs as UInt8, rhs as UInt8): 104 return lhs == rhs 105 case let (lhs as UInt16, rhs as UInt16): 106 return lhs == rhs 107 case let (lhs as UInt32, rhs as UInt32): 108 return lhs == rhs 109 case let (lhs as UInt64, rhs as UInt64): 110 return lhs == rhs 111 case let (lhs as Float, rhs as Float): 112 return lhs == rhs 113 case let (lhs as Double, rhs as Double): 114 return lhs == rhs 115 case let (lhs as String, rhs as String): 116 return lhs == rhs 117 case let (lhs as [String: AnyDecodable], rhs as [String: AnyDecodable]): 118 return lhs == rhs 119 case let (lhs as [AnyDecodable], rhs as [AnyDecodable]): 120 return lhs == rhs 121 default: 122 return false 123 } 124 } 125} 126 127extension AnyDecodable: CustomStringConvertible { 128 var description: String { 129 switch value { 130 case is Void: 131 return String(describing: nil as Any?) 132 case let value as CustomStringConvertible: 133 return value.description 134 default: 135 return String(describing: value) 136 } 137 } 138} 139 140extension AnyDecodable: CustomDebugStringConvertible { 141 var debugDescription: String { 142 switch value { 143 case let value as CustomDebugStringConvertible: 144 return "AnyDecodable(\(value.debugDescription))" 145 default: 146 return "AnyDecodable(\(description))" 147 } 148 } 149} 150 151extension AnyDecodable: Hashable { 152 func hash(into hasher: inout Hasher) { 153 switch value { 154 case let value as Bool: 155 hasher.combine(value) 156 case let value as Int: 157 hasher.combine(value) 158 case let value as Int8: 159 hasher.combine(value) 160 case let value as Int16: 161 hasher.combine(value) 162 case let value as Int32: 163 hasher.combine(value) 164 case let value as Int64: 165 hasher.combine(value) 166 case let value as UInt: 167 hasher.combine(value) 168 case let value as UInt8: 169 hasher.combine(value) 170 case let value as UInt16: 171 hasher.combine(value) 172 case let value as UInt32: 173 hasher.combine(value) 174 case let value as UInt64: 175 hasher.combine(value) 176 case let value as Float: 177 hasher.combine(value) 178 case let value as Double: 179 hasher.combine(value) 180 case let value as String: 181 hasher.combine(value) 182 case let value as [String: AnyDecodable]: 183 hasher.combine(value) 184 case let value as [AnyDecodable]: 185 hasher.combine(value) 186 default: 187 break 188 } 189 } 190} 191 192// swiftlint:enable cyclomatic_complexity 193// swiftlint:enable line_length 194// swiftlint:enable type_name