Skip to content

Full compatibility with the "ExistentialAny" upcoming feature #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
//===----------------------------------------------------------------------===//
import PackageDescription

// General Swift-settings for all targets.
let swiftSettings: [SwiftSetting] = [
// https://github.com/apple/swift-evolution/blob/main/proposals/0335-existential-any.md
// Require `any` for existential types.
.enableUpcomingFeature("ExistentialAny")
]

let package = Package(
name: "swift-openapi-runtime",
platforms: [
Expand All @@ -31,11 +38,13 @@ let package = Package(
targets: [
.target(
name: "OpenAPIRuntime",
dependencies: []
dependencies: [],
swiftSettings: swiftSettings
),
.testTarget(
name: "OpenAPIRuntimeTests",
dependencies: ["OpenAPIRuntime"]
dependencies: ["OpenAPIRuntime"],
swiftSettings: swiftSettings
),
]
)
38 changes: 19 additions & 19 deletions Sources/OpenAPIRuntime/Base/OpenAPIValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@
public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {

/// The underlying dynamic value.
public var value: Sendable?
public var value: (any Sendable)?

/// Creates a new container with the given validated value.
/// - Parameter value: A value of a JSON-compatible type, such as `String`,
/// `[Any]`, and `[String: Any]`.
init(validatedValue value: Sendable?) {
init(validatedValue value: (any Sendable)?) {
self.value = value
}

Expand All @@ -62,7 +62,7 @@ public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {
/// - Parameter value: An untyped value.
/// - Returns: A cast value if supported.
/// - Throws: When the value is not supported.
static func tryCast(_ value: (any Sendable)?) throws -> Sendable? {
static func tryCast(_ value: (any Sendable)?) throws -> (any Sendable)? {
guard let value = value else {
return nil
}
Expand Down Expand Up @@ -98,7 +98,7 @@ public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {

// MARK: Decodable

public init(from decoder: Decoder) throws {
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
if container.decodeNil() {
self.init(validatedValue: nil)
Expand All @@ -124,7 +124,7 @@ public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {

// MARK: Encodable

public func encode(to encoder: Encoder) throws {
public func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
guard let value = value else {
try container.encodeNil()
Expand Down Expand Up @@ -171,15 +171,15 @@ public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {
return lhs == rhs
case let (lhs as String, rhs as String):
return lhs == rhs
case let (lhs as [Sendable?], rhs as [Sendable?]):
case let (lhs as [(any Sendable)?], rhs as [(any Sendable)?]):
guard lhs.count == rhs.count else {
return false
}
return zip(lhs, rhs)
.allSatisfy { lhs, rhs in
OpenAPIValueContainer(validatedValue: lhs) == OpenAPIValueContainer(validatedValue: rhs)
}
case let (lhs as [String: Sendable?], rhs as [String: Sendable?]):
case let (lhs as [String: (any Sendable)?], rhs as [String: (any Sendable)?]):
guard lhs.count == rhs.count else {
return false
}
Expand Down Expand Up @@ -211,11 +211,11 @@ public struct OpenAPIValueContainer: Codable, Equatable, Hashable, Sendable {
hasher.combine(value)
case let value as String:
hasher.combine(value)
case let value as [Sendable]:
case let value as [any Sendable]:
for item in value {
hasher.combine(OpenAPIValueContainer(validatedValue: item))
}
case let value as [String: Sendable]:
case let value as [String: any Sendable]:
for (key, itemValue) in value {
hasher.combine(key)
hasher.combine(OpenAPIValueContainer(validatedValue: itemValue))
Expand Down Expand Up @@ -281,11 +281,11 @@ extension OpenAPIValueContainer: ExpressibleByFloatLiteral {
public struct OpenAPIObjectContainer: Codable, Equatable, Hashable, Sendable {

/// The underlying dynamic dictionary value.
public var value: [String: Sendable?]
public var value: [String: (any Sendable)?]

/// Creates a new container with the given validated dictionary.
/// - Parameter value: A dictionary value.
init(validatedValue value: [String: Sendable?]) {
init(validatedValue value: [String: (any Sendable)?]) {
self.value = value
}

Expand All @@ -311,21 +311,21 @@ public struct OpenAPIObjectContainer: Codable, Equatable, Hashable, Sendable {
/// - Parameter value: A dictionary with untyped values.
/// - Returns: A cast dictionary if values are supported.
/// - Throws: If an unsupported value is found.
static func tryCast(_ value: [String: Any?]) throws -> [String: Sendable?] {
static func tryCast(_ value: [String: Any?]) throws -> [String: (any Sendable)?] {
return try value.mapValues(OpenAPIValueContainer.tryCast(_:))
}

// MARK: Decodable

public init(from decoder: Decoder) throws {
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
let item = try container.decode([String: OpenAPIValueContainer].self)
self.init(validatedValue: item.mapValues(\.value))
}

// MARK: Encodable

public func encode(to encoder: Encoder) throws {
public func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(value.mapValues(OpenAPIValueContainer.init(validatedValue:)))
}
Expand Down Expand Up @@ -385,11 +385,11 @@ public struct OpenAPIObjectContainer: Codable, Equatable, Hashable, Sendable {
public struct OpenAPIArrayContainer: Codable, Equatable, Hashable, Sendable {

/// The underlying dynamic array value.
public var value: [Sendable?]
public var value: [(any Sendable)?]

/// Creates a new container with the given validated array.
/// - Parameter value: An array value.
init(validatedValue value: [Sendable?]) {
init(validatedValue value: [(any Sendable)?]) {
self.value = value
}

Expand All @@ -414,21 +414,21 @@ public struct OpenAPIArrayContainer: Codable, Equatable, Hashable, Sendable {
/// Returns the specified value cast to an array of supported values.
/// - Parameter value: An array with untyped values.
/// - Returns: A cast value if values are supported, nil otherwise.
static func tryCast(_ value: [Any?]) throws -> [Sendable?] {
static func tryCast(_ value: [Any?]) throws -> [(any Sendable)?] {
return try value.map(OpenAPIValueContainer.tryCast(_:))
}

// MARK: Decodable

public init(from decoder: Decoder) throws {
public init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
let item = try container.decode([OpenAPIValueContainer].self)
self.init(validatedValue: item.map(\.value))
}

// MARK: Encodable

public func encode(to encoder: Encoder) throws {
public func encode(to encoder: any Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(value.map(OpenAPIValueContainer.init(validatedValue:)))
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/OpenAPIRuntime/Conversion/CodableExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ extension Decoder {
guard !unknownKeys.isEmpty else {
return .init()
}
let keyValuePairs: [(String, Sendable?)] = try unknownKeys.map { key in
let keyValuePairs: [(String, (any Sendable)?)] = try unknownKeys.map { key in
(
key.stringValue,
try container.decode(
Expand Down
8 changes: 4 additions & 4 deletions Sources/OpenAPIRuntime/Conversion/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension DateTranscoder where Self == ISO8601DateTranscoder {

extension JSONEncoder.DateEncodingStrategy {
/// Encode the `Date` as a custom value encoded using the given ``DateTranscoder``.
static func from(dateTranscoder: DateTranscoder) -> Self {
static func from(dateTranscoder: any DateTranscoder) -> Self {
return .custom { date, encoder in
let dateAsString = try dateTranscoder.encode(date)
var container = encoder.singleValueContainer()
Expand All @@ -66,7 +66,7 @@ extension JSONEncoder.DateEncodingStrategy {

extension JSONDecoder.DateDecodingStrategy {
/// Decode the `Date` as a custom value decoded by the given ``DateTranscoder``.
static func from(dateTranscoder: DateTranscoder) -> Self {
static func from(dateTranscoder: any DateTranscoder) -> Self {
return .custom { decoder in
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
Expand All @@ -79,15 +79,15 @@ extension JSONDecoder.DateDecodingStrategy {
public struct Configuration: Sendable {

/// The transcoder used when converting between date and string values.
public var dateTranscoder: DateTranscoder
public var dateTranscoder: any DateTranscoder

/// Creates a new configuration with the specified values.
///
/// - Parameters:
/// - dateTranscoder: The transcoder to use when converting between date
/// and string values.
public init(
dateTranscoder: DateTranscoder = .iso8601
dateTranscoder: any DateTranscoder = .iso8601
) {
self.dateTranscoder = dateTranscoder
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenAPIRuntime/Deprecated/Deprecated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ extension Converter {
guard let value else {
return
}
if let value = value as? _StringConvertible {
if let value = value as? (any _StringConvertible) {
headerFields.add(name: name, value: value.description)
return
}
Expand All @@ -223,7 +223,7 @@ extension Converter {
guard let stringValue = headerFields.firstValue(name: name) else {
return nil
}
if let myType = T.self as? _StringConvertible.Type {
if let myType = T.self as? any _StringConvertible.Type {
return myType.init(stringValue).map { $0 as! T }
}
let data = Data(stringValue.utf8)
Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIRuntime/Errors/ClientError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public struct ClientError: Error {
public var response: Response?

/// The underlying error that caused the operation to fail.
public var underlyingError: Error
public var underlyingError: any Error

/// Creates a new error.
/// - Parameters:
Expand All @@ -65,7 +65,7 @@ public struct ClientError: Error {
request: Request? = nil,
baseURL: URL? = nil,
response: Response? = nil,
underlyingError: Error
underlyingError: any Error
) {
self.operationID = operationID
self.operationInput = operationInput
Expand All @@ -78,7 +78,7 @@ public struct ClientError: Error {
// MARK: Private

fileprivate var underlyingErrorDescription: String {
guard let prettyError = underlyingError as? PrettyStringConvertible else {
guard let prettyError = underlyingError as? (any PrettyStringConvertible) else {
return underlyingError.localizedDescription
}
return prettyError.prettyDescription
Expand Down
4 changes: 2 additions & 2 deletions Sources/OpenAPIRuntime/Errors/RuntimeError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ internal enum RuntimeError: Error, CustomStringConvertible, LocalizedError, Pret
case missingRequiredRequestBody

// Transport/Handler
case transportFailed(Error)
case handlerFailed(Error)
case transportFailed(any Error)
case handlerFailed(any Error)

// MARK: CustomStringConvertible

Expand Down
6 changes: 3 additions & 3 deletions Sources/OpenAPIRuntime/Errors/ServerError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public struct ServerError: Error {
public var operationOutput: (any Sendable)?

/// The underlying error that caused the operation to fail.
public var underlyingError: Error
public var underlyingError: any Error

/// Creates a new error.
/// - Parameters:
Expand All @@ -52,7 +52,7 @@ public struct ServerError: Error {
requestMetadata: ServerRequestMetadata,
operationInput: (any Sendable)? = nil,
operationOutput: (any Sendable)? = nil,
underlyingError: Error
underlyingError: (any Error)
) {
self.operationID = operationID
self.request = request
Expand All @@ -65,7 +65,7 @@ public struct ServerError: Error {
// MARK: Private

fileprivate var underlyingErrorDescription: String {
guard let prettyError = underlyingError as? PrettyStringConvertible else {
guard let prettyError = underlyingError as? (any PrettyStringConvertible) else {
return underlyingError.localizedDescription
}
return prettyError.prettyDescription
Expand Down
18 changes: 9 additions & 9 deletions Sources/OpenAPIRuntime/Interface/UniversalClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ public struct UniversalClient: Sendable {
public let converter: Converter

/// Type capable of sending HTTP requests and receiving HTTP responses.
public var transport: ClientTransport
public var transport: any ClientTransport

/// Middlewares to be invoked before `transport`.
public var middlewares: [ClientMiddleware]
public var middlewares: [any ClientMiddleware]

/// Internal initializer that takes an initialized `Converter`.
internal init(
serverURL: URL,
converter: Converter,
transport: ClientTransport,
middlewares: [ClientMiddleware]
transport: any ClientTransport,
middlewares: [any ClientMiddleware]
) {
self.serverURL = serverURL
self.converter = converter
Expand All @@ -56,8 +56,8 @@ public struct UniversalClient: Sendable {
public init(
serverURL: URL = .defaultOpenAPIServerURL,
configuration: Configuration = .init(),
transport: ClientTransport,
middlewares: [ClientMiddleware] = []
transport: any ClientTransport,
middlewares: [any ClientMiddleware] = []
) {
self.init(
serverURL: serverURL,
Expand Down Expand Up @@ -93,7 +93,7 @@ public struct UniversalClient: Sendable {
@Sendable
func wrappingErrors<R>(
work: () async throws -> R,
mapError: (Error) -> Error
mapError: (any Error) -> any Error
) async throws -> R {
do {
return try await work()
Expand All @@ -106,8 +106,8 @@ public struct UniversalClient: Sendable {
request: Request? = nil,
baseURL: URL? = nil,
response: Response? = nil,
error: Error
) -> Error {
error: any Error
) -> any Error {
ClientError(
operationID: operationID,
operationInput: input,
Expand Down
Loading