From 34ab2ec7b411ad354a9a2f616689c0633abb3889 Mon Sep 17 00:00:00 2001 From: Gus Cairo Date: Tue, 13 Jan 2026 13:53:34 +0000 Subject: [PATCH] Add SocketAddress to NetworkTypes --- Sources/NetworkTypes/SocketAddress.swift | 108 +++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 Sources/NetworkTypes/SocketAddress.swift diff --git a/Sources/NetworkTypes/SocketAddress.swift b/Sources/NetworkTypes/SocketAddress.swift new file mode 100644 index 0000000..3868c0e --- /dev/null +++ b/Sources/NetworkTypes/SocketAddress.swift @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift HTTP API Proposal open source project +// +// Copyright (c) 2026 Apple Inc. and the Swift HTTP API Proposal project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of Swift HTTP API Proposal project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +/// An address to which a socket may connect or bind to. +public struct SocketAddress: Hashable, Sendable { + /// Represents an IPv4 address. + public struct IPv4: Hashable, Sendable { + /// The resolved host address. + public var host: String + /// The port to connect to. + public var port: Int + + /// Creates a new IPv4 address. + /// + /// - Parameters: + /// - host: Resolved host address. + /// - port: Port to connect to. + public init(host: String, port: Int) { + self.host = host + self.port = port + } + } + + /// Represents an IPv6 address. + public struct IPv6: Hashable, Sendable { + /// The resolved host address. + public var host: String + /// The port to connect to. + public var port: Int + + /// Creates a new IPv6 address. + /// + /// - Parameters: + /// - host: Resolved host address. + /// - port: Port to connect to. + public init(host: String, port: Int) { + self.host = host + self.port = port + } + } + + enum Base: Hashable, Sendable { + case ipv4(IPv4) + case ipv6(IPv6) + } + + let base: Base + + /// Creates an IPv4 socket address. + public static func ipv4(host: String, port: Int) -> Self { + Self(base: .ipv4(.init(host: host, port: port))) + } + + /// Creates an IPv6 socket address. + public static func ipv6(host: String, port: Int) -> Self { + Self(base: .ipv6(.init(host: host, port: port))) + } + + /// Returns the address as an IPv4 address, if possible. + public var ipv4: IPv4? { + guard case .ipv4(let address) = self.base else { + return nil + } + + return address + } + + /// Returns the address as an IPv6 address, if possible. + public var ipv6: IPv6? { + guard case .ipv6(let address) = self.base else { + return nil + } + + return address + } + + /// The ``SocketAddress``'s host. + public var host: String { + switch self.base { + case .ipv4(let ipv4): + return ipv4.host + case .ipv6(let ipv6): + return ipv6.host + } + } + + /// The ``SocketAddress``'s port. + public var port: Int { + switch self.base { + case .ipv4(let ipv4): + return ipv4.port + + case .ipv6(let ipv6): + return ipv6.port + } + } +}