// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. import Foundation /// A type that describes any value that can be used in a request or response object. public protocol APIValue {} extension NSNull: APIValue {} extension String: APIValue {} extension Int: APIValue {} extension Double: APIValue {} extension Bool: APIValue {} extension Optional: APIValue where Wrapped: APIValue {} extension Array: APIValue where Element: APIValue {} extension Dictionary: APIValue where Key == String, Value: APIValue {} enum APIValueConversionError: Error { case invalidType } /// A type-erased wrapper for passing around ``APIValue`` values. public struct AnyValue: Codable { // This is a type-erased wrapper which allows us to store Serializable values in collections, as well as handle // JSON encoding and decoding. private var _serialize: (_ format: SerializableFormat) throws -> String private var _serializeQueryParameters: (_ format: SerializableFormat) throws -> [QueryParameter] private var _description: () -> String private var _serializable: () -> any Serializable init(serializable: Serializable) { _serialize = { format in try serializable.serialize(with: format) } _serializeQueryParameters = { format in try serializable.serializeQueryParameters(with: format) } _serializable = { return serializable } _description = { if let serializable = serializable as? CustomStringConvertible { return serializable.description } else { return String(describing: serializable) } } } /// Creates an object from an `NSNull` value public init(_ null: NSNull) { self.init(serializable: null) } /// Creates an object from a string value public init(_ string: String) { self.init(serializable: string) } /// Creates an object from an integer value public init(_ int: Int) { self.init(serializable: int) } /// Creates an object from a double value public init(_ double: Double) { self.init(serializable: double) } /// Creates an object from a boolean value public init(_ bool: Bool) { self.init(serializable: bool) } /// Creates an object from any ``APIValue`` value public init(_ value: APIValue) throws { guard let serializable = value as? Serializable else { throw APIValueConversionError.invalidType } self.init(serializable: serializable) } /// Creates an object from an optional value public init(_ optional: Optional) throws { guard let serializable = optional as? Serializable else { throw APIValueConversionError.invalidType } self.init(serializable: serializable) } /// Creates an object from an array value public init(_ array: Array) throws { guard let serializable = array as? Serializable else { throw APIValueConversionError.invalidType } self.init(serializable: serializable) } /// Creates an object from a dictionary value public init(_ dictionary: Dictionary) throws { guard let serializable = dictionary as? Serializable else { throw APIValueConversionError.invalidType } self.init(serializable: serializable) } // MARK: - Codable public init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() if container.decodeNil() { self.init(serializable: NSNull()) } else if let boolValue = try? container.decode(Bool.self) { self.init(serializable: boolValue) } else if let intValue = try? container.decode(Int.self) { self.init(serializable: intValue) } else if let doubleValue = try? container.decode(Double.self) { self.init(serializable: doubleValue) } else if let stringValue = try? container.decode(String.self) { self.init(serializable: stringValue) } else if let arrayValue = try? container.decode([AnyValue].self) { self.init(serializable: arrayValue) } else if let dictionaryValue = try? container.decode([String: AnyValue].self) { self.init(serializable: dictionaryValue) } else { throw DecodingError.dataCorruptedError( in: container, debugDescription: "Unsupported value in container. Is this valid JSON?" ) } } public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() let value = _serializable() if value is NSNull { try container.encodeNil() } else if let boolValue = value as? Bool { try container.encode(boolValue) } else if let intValue = value as? Int { try container.encode(intValue) } else if let doubleValue = value as? Double { try container.encode(doubleValue) } else if let stringValue = value as? String { try container.encode(stringValue) } else if let arrayValue = value as? [AnyValue] { try container.encode(arrayValue) } else if let dictionaryValue = value as? [String: AnyValue] { try container.encode(dictionaryValue) } else if let encodableValue = value as? Encodable { try container.encode(encodableValue) } else { let context = EncodingError.Context(codingPath: container.codingPath, debugDescription: "Cannot encode value") throw EncodingError.invalidValue(value, context) } } } // MARK: - Serializable extension AnyValue: Serializable { func serialize(with format: SerializableFormat) throws -> String { return try _serialize(format) } func serializeQueryParameters(with format: SerializableFormat) throws -> [QueryParameter] { return try _serializeQueryParameters(format) } } // MARK: - Helpers extension AnyValue { subscript(key: String) -> AnyValue? { if let serializable = _serializable() as? [String: Serializable], let value = serializable[key] { return AnyValue(serializable: value) } else { return nil } } func `as`(type: T.Type) -> T? { return _serializable() as? T } func asArray(elementType: T.Type) -> [T]? { guard let array = _serializable() as? [AnyValue] else { return nil } var result: [T] = [] for element in array { guard let element = element.as(type: T.self) else { return nil } result.append(element) } return result } } // MARK: - Equatable extension AnyValue: Equatable { public static func == (lhs: AnyValue, rhs: AnyValue) -> Bool { let lhsValue = lhs._serializable() let rhsValue = rhs._serializable() switch (lhsValue, rhsValue) { case is (NSNull, NSNull): return true case let (lhsValue as Bool, rhsValue as Bool): return lhsValue == rhsValue case let (lhsValue as Int, rhsValue as Int): return lhsValue == rhsValue case let (lhsValue as Double, rhsValue as Double): return lhsValue == rhsValue case let (lhsValue as String, rhsValue as String): return lhsValue == rhsValue case let (lhsValue as [AnyValue], rhsValue as [AnyValue]): return lhsValue == rhsValue case let (lhsValue as [String: AnyValue], rhsValue as [String: AnyValue]): return lhsValue == rhsValue default: return false } } } // MARK: - CustomStringConvertible extension AnyValue: CustomStringConvertible { public var description: String { return _description() } }