//===----------------------------------------------------------------------===// // Copyright © 2025 Apple Inc. and the container project authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //===----------------------------------------------------------------------===// import ContainerBuildIR struct ExposeInstruction: DockerInstruction { let ports: [String] init(_ ports: [String]) { self.ports = ports } internal init(ports: [PortSpec]) { self.ports = ports.map { $0.stringValue } } func accept(_ visitor: DockerInstructionVisitor) throws { try visitor.visit(self) } } func parsePort(_ p: String) throws -> PortSpec { let parts = p.split(separator: "/", maxSplits: 1).map(String.init) guard let rangePart = parts.first, !rangePart.isEmpty else { throw ParseError.invalidOption(p) } // parse the port range let range = rangePart.split(separator: "-", maxSplits: 1) guard let port = UInt16(range[0]), port != 0 else { throw ParseError.invalidOption(p) } // parse the end of the range if it exists let end = range.count == 2 ? UInt16(range[1]) : nil if range.count == 2, end == nil { throw ParseError.invalidOption(p) } if end != nil, end == 0 { throw ParseError.invalidOption(p) } // parse the protocol if one was specified let protocolType: PortSpec.NetworkProtocol = try { if parts.count == 2 { guard let proto = PortSpec.NetworkProtocol(rawValue: String(parts[1]).lowercased()) else { throw ParseError.invalidOption(p) } return proto } return .tcp }() return PortSpec(port: port, endPort: end, protocol: protocolType) }