Repository: apple/swift-nio
File: Sources/NIOPosix/HappyEyeballs.swift (Swift)

Code before:

    /// The error we encountered doing the DNS AAAA lookup, if any.
    public fileprivate(set) var dnsAAAAError: Error? = nil

    /// The errors we encountered during the connection attempts.
    public fileprivate(set) var connectionErrors: [SingleConnectionFailure] = []

    fileprivate init(host: String, port: Int) {
        self.host = host
        self.port = port
    }
}

extension NIOConnectionError: CustomStringConvertible {
    public var description: String {
        if let dnsError = (dnsAError ?? dnsAAAAError) {
             return "DNS error: \(dnsError.localizedDescription)"
         }

         if !connectionErrors.isEmpty {
             let descriptions = connectionErrors.map {
                 if let channelError = $0.error as? ChannelError {
                     channelError.description
                 } else {
                     $0.error.localizedDescription
                 }
             }

             return "Connection errors: \(descriptions.joined(separator: ", "))"
         }

         return "Unknown error"
     }
}

/// A simple iterator that manages iterating over the possible targets.
///
/// This iterator knows how to merge together the A and AAAA records in a sensible way:
/// specifically, it keeps track of what the last address family it emitted was, and emits the
/// address of the opposite family next.
private struct TargetIterator: IteratorProtocol {
    typealias Element = SocketAddress

    private enum AddressFamily {
        case v4
        case v6
    }

    private var previousAddressFamily: AddressFamily = .v4
    private var aQueryResults: [SocketAddress] = []
    private var aaaaQueryResults: [SocketAddress] = []

Review comment (suggestion):
No need to do any casting here and avoid using `localizedDescription`. Just use `String(describing: $0)` here.

Code after:

    /// The error we encountered doing the DNS AAAA lookup, if any.
    public fileprivate(set) var dnsAAAAError: Error? = nil

    /// The errors we encountered during the connection attempts.
    public fileprivate(set) var connectionErrors: [SingleConnectionFailure] = []

    fileprivate init(host: String, port: Int) {
        self.host = host
        self.port = port
    }
}

extension NIOConnectionError: CustomStringConvertible {
    public var description: String {
        if let dnsError = (self.dnsAError ?? self.dnsAAAAError) {
            return "DNS error: \(dnsError)"
        }

        if !self.connectionErrors.isEmpty {
            let descriptions = self.connectionErrors.map {
                String(describing: $0)
            }

            return "Connection errors: \(descriptions.joined(separator: ", "))"
        }

        return "NIOConnectionError: unknown"
    }
}

/// A simple iterator that manages iterating over the possible targets.
///
/// This iterator knows how to merge together the A and AAAA records in a sensible way:
/// specifically, it keeps track of what the last address family it emitted was, and emits the
/// address of the opposite family next.
private struct TargetIterator: IteratorProtocol {
    typealias Element = SocketAddress

    private enum AddressFamily {
        case v4
        case v6
    }

    private var previousAddressFamily: AddressFamily = .v4
    private var aQueryResults: [SocketAddress] = []
    private var aaaaQueryResults: [SocketAddress] = []

    mutating func aResultsAvailable(_ results: [SocketAddress]) {
        aQueryResults.append(contentsOf: results)
    }