From 37870456523e228ab88afa8b6ff7c7f0c3763675 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Wed, 21 Aug 2024 17:34:27 +0100 Subject: [PATCH 1/6] Generate --- .../Generated/route_guide.grpc.swift | 523 ++++++++++++++++++ .../Generated/route_guide.pb.swift | 387 +++++++++++++ 2 files changed, 910 insertions(+) create mode 100644 Examples/v2/route-guide/Generated/route_guide.grpc.swift create mode 100644 Examples/v2/route-guide/Generated/route_guide.pb.swift diff --git a/Examples/v2/route-guide/Generated/route_guide.grpc.swift b/Examples/v2/route-guide/Generated/route_guide.grpc.swift new file mode 100644 index 000000000..e2fd21a5f --- /dev/null +++ b/Examples/v2/route-guide/Generated/route_guide.grpc.swift @@ -0,0 +1,523 @@ +// Copyright 2015 gRPC authors. +// +// 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 +// +// http://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. + +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the gRPC Swift generator plugin for the protocol buffer compiler. +// Source: route_guide.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/grpc/grpc-swift + +internal import GRPCCore +internal import GRPCProtobuf + +internal enum Routeguide_RouteGuide { + internal static let descriptor = GRPCCore.ServiceDescriptor.routeguide_RouteGuide + internal enum Method { + internal enum GetFeature { + internal typealias Input = Routeguide_Point + internal typealias Output = Routeguide_Feature + internal static let descriptor = GRPCCore.MethodDescriptor( + service: Routeguide_RouteGuide.descriptor.fullyQualifiedService, + method: "GetFeature" + ) + } + internal enum ListFeatures { + internal typealias Input = Routeguide_Rectangle + internal typealias Output = Routeguide_Feature + internal static let descriptor = GRPCCore.MethodDescriptor( + service: Routeguide_RouteGuide.descriptor.fullyQualifiedService, + method: "ListFeatures" + ) + } + internal enum RecordRoute { + internal typealias Input = Routeguide_Point + internal typealias Output = Routeguide_RouteSummary + internal static let descriptor = GRPCCore.MethodDescriptor( + service: Routeguide_RouteGuide.descriptor.fullyQualifiedService, + method: "RecordRoute" + ) + } + internal enum RouteChat { + internal typealias Input = Routeguide_RouteNote + internal typealias Output = Routeguide_RouteNote + internal static let descriptor = GRPCCore.MethodDescriptor( + service: Routeguide_RouteGuide.descriptor.fullyQualifiedService, + method: "RouteChat" + ) + } + internal static let descriptors: [GRPCCore.MethodDescriptor] = [ + GetFeature.descriptor, + ListFeatures.descriptor, + RecordRoute.descriptor, + RouteChat.descriptor + ] + } + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + internal typealias StreamingServiceProtocol = Routeguide_RouteGuideStreamingServiceProtocol + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + internal typealias ServiceProtocol = Routeguide_RouteGuideServiceProtocol + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + internal typealias ClientProtocol = Routeguide_RouteGuideClientProtocol + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + internal typealias Client = Routeguide_RouteGuideClient +} + +extension GRPCCore.ServiceDescriptor { + internal static let routeguide_RouteGuide = Self( + package: "routeguide", + service: "RouteGuide" + ) +} + +/// Interface exported by the server. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +internal protocol Routeguide_RouteGuideStreamingServiceProtocol: GRPCCore.RegistrableRPCService { + /// A simple RPC. + /// + /// Obtains the feature at a given position. + /// + /// A feature with an empty name is returned if there's no feature at the given + /// position. + func getFeature(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream + + /// A server-to-client streaming RPC. + /// + /// Obtains the Features available within the given Rectangle. Results are + /// streamed rather than returned at once (e.g. in a response message with a + /// repeated field), as the rectangle may cover a large area and contain a + /// huge number of features. + func listFeatures(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream + + /// A client-to-server streaming RPC. + /// + /// Accepts a stream of Points on a route being traversed, returning a + /// RouteSummary when traversal is completed. + func recordRoute(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream + + /// A Bidirectional streaming RPC. + /// + /// Accepts a stream of RouteNotes sent while a route is being traversed, + /// while receiving other RouteNotes (e.g. from other users). + func routeChat(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream +} + +/// Conformance to `GRPCCore.RegistrableRPCService`. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension Routeguide_RouteGuide.StreamingServiceProtocol { + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + internal func registerMethods(with router: inout GRPCCore.RPCRouter) { + router.registerHandler( + forMethod: Routeguide_RouteGuide.Method.GetFeature.descriptor, + deserializer: GRPCProtobuf.ProtobufDeserializer(), + serializer: GRPCProtobuf.ProtobufSerializer(), + handler: { request in + try await self.getFeature(request: request) + } + ) + router.registerHandler( + forMethod: Routeguide_RouteGuide.Method.ListFeatures.descriptor, + deserializer: GRPCProtobuf.ProtobufDeserializer(), + serializer: GRPCProtobuf.ProtobufSerializer(), + handler: { request in + try await self.listFeatures(request: request) + } + ) + router.registerHandler( + forMethod: Routeguide_RouteGuide.Method.RecordRoute.descriptor, + deserializer: GRPCProtobuf.ProtobufDeserializer(), + serializer: GRPCProtobuf.ProtobufSerializer(), + handler: { request in + try await self.recordRoute(request: request) + } + ) + router.registerHandler( + forMethod: Routeguide_RouteGuide.Method.RouteChat.descriptor, + deserializer: GRPCProtobuf.ProtobufDeserializer(), + serializer: GRPCProtobuf.ProtobufSerializer(), + handler: { request in + try await self.routeChat(request: request) + } + ) + } +} + +/// Interface exported by the server. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +internal protocol Routeguide_RouteGuideServiceProtocol: Routeguide_RouteGuide.StreamingServiceProtocol { + /// A simple RPC. + /// + /// Obtains the feature at a given position. + /// + /// A feature with an empty name is returned if there's no feature at the given + /// position. + func getFeature(request: GRPCCore.ServerRequest.Single) async throws -> GRPCCore.ServerResponse.Single + + /// A server-to-client streaming RPC. + /// + /// Obtains the Features available within the given Rectangle. Results are + /// streamed rather than returned at once (e.g. in a response message with a + /// repeated field), as the rectangle may cover a large area and contain a + /// huge number of features. + func listFeatures(request: GRPCCore.ServerRequest.Single) async throws -> GRPCCore.ServerResponse.Stream + + /// A client-to-server streaming RPC. + /// + /// Accepts a stream of Points on a route being traversed, returning a + /// RouteSummary when traversal is completed. + func recordRoute(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Single + + /// A Bidirectional streaming RPC. + /// + /// Accepts a stream of RouteNotes sent while a route is being traversed, + /// while receiving other RouteNotes (e.g. from other users). + func routeChat(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream +} + +/// Partial conformance to `Routeguide_RouteGuideStreamingServiceProtocol`. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension Routeguide_RouteGuide.ServiceProtocol { + internal func getFeature(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream { + let response = try await self.getFeature(request: GRPCCore.ServerRequest.Single(stream: request)) + return GRPCCore.ServerResponse.Stream(single: response) + } + + internal func listFeatures(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream { + let response = try await self.listFeatures(request: GRPCCore.ServerRequest.Single(stream: request)) + return response + } + + internal func recordRoute(request: GRPCCore.ServerRequest.Stream) async throws -> GRPCCore.ServerResponse.Stream { + let response = try await self.recordRoute(request: request) + return GRPCCore.ServerResponse.Stream(single: response) + } +} + +/// Interface exported by the server. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +internal protocol Routeguide_RouteGuideClientProtocol: Sendable { + /// A simple RPC. + /// + /// Obtains the feature at a given position. + /// + /// A feature with an empty name is returned if there's no feature at the given + /// position. + func getFeature( + request: GRPCCore.ClientRequest.Single, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> R + ) async throws -> R where R: Sendable + + /// A server-to-client streaming RPC. + /// + /// Obtains the Features available within the given Rectangle. Results are + /// streamed rather than returned at once (e.g. in a response message with a + /// repeated field), as the rectangle may cover a large area and contain a + /// huge number of features. + func listFeatures( + request: GRPCCore.ClientRequest.Single, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> R + ) async throws -> R where R: Sendable + + /// A client-to-server streaming RPC. + /// + /// Accepts a stream of Points on a route being traversed, returning a + /// RouteSummary when traversal is completed. + func recordRoute( + request: GRPCCore.ClientRequest.Stream, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> R + ) async throws -> R where R: Sendable + + /// A Bidirectional streaming RPC. + /// + /// Accepts a stream of RouteNotes sent while a route is being traversed, + /// while receiving other RouteNotes (e.g. from other users). + func routeChat( + request: GRPCCore.ClientRequest.Stream, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> R + ) async throws -> R where R: Sendable +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension Routeguide_RouteGuide.ClientProtocol { + internal func getFeature( + request: GRPCCore.ClientRequest.Single, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> R = { + try $0.message + } + ) async throws -> R where R: Sendable { + try await self.getFeature( + request: request, + serializer: GRPCProtobuf.ProtobufSerializer(), + deserializer: GRPCProtobuf.ProtobufDeserializer(), + options: options, + body + ) + } + + internal func listFeatures( + request: GRPCCore.ClientRequest.Single, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> R + ) async throws -> R where R: Sendable { + try await self.listFeatures( + request: request, + serializer: GRPCProtobuf.ProtobufSerializer(), + deserializer: GRPCProtobuf.ProtobufDeserializer(), + options: options, + body + ) + } + + internal func recordRoute( + request: GRPCCore.ClientRequest.Stream, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> R = { + try $0.message + } + ) async throws -> R where R: Sendable { + try await self.recordRoute( + request: request, + serializer: GRPCProtobuf.ProtobufSerializer(), + deserializer: GRPCProtobuf.ProtobufDeserializer(), + options: options, + body + ) + } + + internal func routeChat( + request: GRPCCore.ClientRequest.Stream, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> R + ) async throws -> R where R: Sendable { + try await self.routeChat( + request: request, + serializer: GRPCProtobuf.ProtobufSerializer(), + deserializer: GRPCProtobuf.ProtobufDeserializer(), + options: options, + body + ) + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension Routeguide_RouteGuide.ClientProtocol { + /// A simple RPC. + /// + /// Obtains the feature at a given position. + /// + /// A feature with an empty name is returned if there's no feature at the given + /// position. + internal func getFeature( + _ message: Routeguide_Point, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> Result = { + try $0.message + } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest.Single( + message: message, + metadata: metadata + ) + return try await self.getFeature( + request: request, + options: options, + handleResponse + ) + } + + /// A server-to-client streaming RPC. + /// + /// Obtains the Features available within the given Rectangle. Results are + /// streamed rather than returned at once (e.g. in a response message with a + /// repeated field), as the rectangle may cover a large area and contain a + /// huge number of features. + internal func listFeatures( + _ message: Routeguide_Rectangle, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest.Single( + message: message, + metadata: metadata + ) + return try await self.listFeatures( + request: request, + options: options, + handleResponse + ) + } + + /// A client-to-server streaming RPC. + /// + /// Accepts a stream of Points on a route being traversed, returning a + /// RouteSummary when traversal is completed. + internal func recordRoute( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer: @Sendable @escaping (GRPCCore.RPCWriter) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> Result = { + try $0.message + } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest.Stream( + metadata: metadata, + producer: requestProducer + ) + return try await self.recordRoute( + request: request, + options: options, + handleResponse + ) + } + + /// A Bidirectional streaming RPC. + /// + /// Accepts a stream of RouteNotes sent while a route is being traversed, + /// while receiving other RouteNotes (e.g. from other users). + internal func routeChat( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer: @Sendable @escaping (GRPCCore.RPCWriter) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest.Stream( + metadata: metadata, + producer: requestProducer + ) + return try await self.routeChat( + request: request, + options: options, + handleResponse + ) + } +} + +/// Interface exported by the server. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +internal struct Routeguide_RouteGuideClient: Routeguide_RouteGuide.ClientProtocol { + private let client: GRPCCore.GRPCClient + + internal init(wrapping client: GRPCCore.GRPCClient) { + self.client = client + } + + /// A simple RPC. + /// + /// Obtains the feature at a given position. + /// + /// A feature with an empty name is returned if there's no feature at the given + /// position. + internal func getFeature( + request: GRPCCore.ClientRequest.Single, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> R = { + try $0.message + } + ) async throws -> R where R: Sendable { + try await self.client.unary( + request: request, + descriptor: Routeguide_RouteGuide.Method.GetFeature.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + handler: body + ) + } + + /// A server-to-client streaming RPC. + /// + /// Obtains the Features available within the given Rectangle. Results are + /// streamed rather than returned at once (e.g. in a response message with a + /// repeated field), as the rectangle may cover a large area and contain a + /// huge number of features. + internal func listFeatures( + request: GRPCCore.ClientRequest.Single, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> R + ) async throws -> R where R: Sendable { + try await self.client.serverStreaming( + request: request, + descriptor: Routeguide_RouteGuide.Method.ListFeatures.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + handler: body + ) + } + + /// A client-to-server streaming RPC. + /// + /// Accepts a stream of Points on a route being traversed, returning a + /// RouteSummary when traversal is completed. + internal func recordRoute( + request: GRPCCore.ClientRequest.Stream, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Single) async throws -> R = { + try $0.message + } + ) async throws -> R where R: Sendable { + try await self.client.clientStreaming( + request: request, + descriptor: Routeguide_RouteGuide.Method.RecordRoute.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + handler: body + ) + } + + /// A Bidirectional streaming RPC. + /// + /// Accepts a stream of RouteNotes sent while a route is being traversed, + /// while receiving other RouteNotes (e.g. from other users). + internal func routeChat( + request: GRPCCore.ClientRequest.Stream, + serializer: some GRPCCore.MessageSerializer, + deserializer: some GRPCCore.MessageDeserializer, + options: GRPCCore.CallOptions = .defaults, + _ body: @Sendable @escaping (GRPCCore.ClientResponse.Stream) async throws -> R + ) async throws -> R where R: Sendable { + try await self.client.bidirectionalStreaming( + request: request, + descriptor: Routeguide_RouteGuide.Method.RouteChat.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + handler: body + ) + } +} \ No newline at end of file diff --git a/Examples/v2/route-guide/Generated/route_guide.pb.swift b/Examples/v2/route-guide/Generated/route_guide.pb.swift new file mode 100644 index 000000000..d5d28f0f9 --- /dev/null +++ b/Examples/v2/route-guide/Generated/route_guide.pb.swift @@ -0,0 +1,387 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: route_guide.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2015 gRPC authors. +// +// 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 +// +// http://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 Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// Points are represented as latitude-longitude pairs in the E7 representation +/// (degrees multiplied by 10**7 and rounded to the nearest integer). +/// Latitudes should be in the range +/- 90 degrees and longitude should be in +/// the range +/- 180 degrees (inclusive). +struct Routeguide_Point: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var latitude: Int32 = 0 + + var longitude: Int32 = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// A latitude-longitude rectangle, represented as two diagonally opposite +/// points "lo" and "hi". +struct Routeguide_Rectangle: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// One corner of the rectangle. + var lo: Routeguide_Point { + get {return _lo ?? Routeguide_Point()} + set {_lo = newValue} + } + /// Returns true if `lo` has been explicitly set. + var hasLo: Bool {return self._lo != nil} + /// Clears the value of `lo`. Subsequent reads from it will return its default value. + mutating func clearLo() {self._lo = nil} + + /// The other corner of the rectangle. + var hi: Routeguide_Point { + get {return _hi ?? Routeguide_Point()} + set {_hi = newValue} + } + /// Returns true if `hi` has been explicitly set. + var hasHi: Bool {return self._hi != nil} + /// Clears the value of `hi`. Subsequent reads from it will return its default value. + mutating func clearHi() {self._hi = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _lo: Routeguide_Point? = nil + fileprivate var _hi: Routeguide_Point? = nil +} + +/// A feature names something at a given point. +/// +/// If a feature could not be named, the name is empty. +struct Routeguide_Feature: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The name of the feature. + var name: String = String() + + /// The point where the feature is detected. + var location: Routeguide_Point { + get {return _location ?? Routeguide_Point()} + set {_location = newValue} + } + /// Returns true if `location` has been explicitly set. + var hasLocation: Bool {return self._location != nil} + /// Clears the value of `location`. Subsequent reads from it will return its default value. + mutating func clearLocation() {self._location = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _location: Routeguide_Point? = nil +} + +/// A RouteNote is a message sent while at a given point. +struct Routeguide_RouteNote: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The location from which the message is sent. + var location: Routeguide_Point { + get {return _location ?? Routeguide_Point()} + set {_location = newValue} + } + /// Returns true if `location` has been explicitly set. + var hasLocation: Bool {return self._location != nil} + /// Clears the value of `location`. Subsequent reads from it will return its default value. + mutating func clearLocation() {self._location = nil} + + /// The message to be sent. + var message: String = String() + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _location: Routeguide_Point? = nil +} + +/// A RouteSummary is received in response to a RecordRoute rpc. +/// +/// It contains the number of individual points received, the number of +/// detected features, and the total distance covered as the cumulative sum of +/// the distance between each point. +struct Routeguide_RouteSummary: Sendable { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The number of points received. + var pointCount: Int32 = 0 + + /// The number of known features passed while traversing the route. + var featureCount: Int32 = 0 + + /// The distance covered in metres. + var distance: Int32 = 0 + + /// The duration of the traversal in seconds. + var elapsedTime: Int32 = 0 + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "routeguide" + +extension Routeguide_Point: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Point" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "latitude"), + 2: .same(proto: "longitude"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self.latitude) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self.longitude) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.latitude != 0 { + try visitor.visitSingularInt32Field(value: self.latitude, fieldNumber: 1) + } + if self.longitude != 0 { + try visitor.visitSingularInt32Field(value: self.longitude, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Routeguide_Point, rhs: Routeguide_Point) -> Bool { + if lhs.latitude != rhs.latitude {return false} + if lhs.longitude != rhs.longitude {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Routeguide_Rectangle: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Rectangle" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "lo"), + 2: .same(proto: "hi"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._lo) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._hi) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._lo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._hi { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Routeguide_Rectangle, rhs: Routeguide_Rectangle) -> Bool { + if lhs._lo != rhs._lo {return false} + if lhs._hi != rhs._hi {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Routeguide_Feature: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Feature" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "location"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self.name) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._location) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.name.isEmpty { + try visitor.visitSingularStringField(value: self.name, fieldNumber: 1) + } + try { if let v = self._location { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Routeguide_Feature, rhs: Routeguide_Feature) -> Bool { + if lhs.name != rhs.name {return false} + if lhs._location != rhs._location {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Routeguide_RouteNote: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".RouteNote" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "location"), + 2: .same(proto: "message"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._location) }() + case 2: try { try decoder.decodeSingularStringField(value: &self.message) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._location { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + if !self.message.isEmpty { + try visitor.visitSingularStringField(value: self.message, fieldNumber: 2) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Routeguide_RouteNote, rhs: Routeguide_RouteNote) -> Bool { + if lhs._location != rhs._location {return false} + if lhs.message != rhs.message {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Routeguide_RouteSummary: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".RouteSummary" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "point_count"), + 2: .standard(proto: "feature_count"), + 3: .same(proto: "distance"), + 4: .standard(proto: "elapsed_time"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self.pointCount) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self.featureCount) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &self.distance) }() + case 4: try { try decoder.decodeSingularInt32Field(value: &self.elapsedTime) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if self.pointCount != 0 { + try visitor.visitSingularInt32Field(value: self.pointCount, fieldNumber: 1) + } + if self.featureCount != 0 { + try visitor.visitSingularInt32Field(value: self.featureCount, fieldNumber: 2) + } + if self.distance != 0 { + try visitor.visitSingularInt32Field(value: self.distance, fieldNumber: 3) + } + if self.elapsedTime != 0 { + try visitor.visitSingularInt32Field(value: self.elapsedTime, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Routeguide_RouteSummary, rhs: Routeguide_RouteSummary) -> Bool { + if lhs.pointCount != rhs.pointCount {return false} + if lhs.featureCount != rhs.featureCount {return false} + if lhs.distance != rhs.distance {return false} + if lhs.elapsedTime != rhs.elapsedTime {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} From 8eddb1f49d881a36103246f5fb1419610f517cdf Mon Sep 17 00:00:00 2001 From: George Barnett Date: Wed, 21 Aug 2024 17:34:33 +0100 Subject: [PATCH 2/6] Add route-guide --- Examples/v2/route-guide/RouteGuide.swift | 26 + .../route-guide/Subcommands/GetFeature.swift | 68 ++ .../Subcommands/ListFeatures.swift | 85 +++ .../route-guide/Subcommands/RecordRoute.swift | 73 ++ .../route-guide/Subcommands/RouteChat.swift | 73 ++ .../v2/route-guide/Subcommands/Serve.swift | 246 ++++++ Examples/v2/route-guide/route_guide_db.json | 702 ++++++++++++++++++ Package@swift-6.swift | 24 + Protos/generate.sh | 13 +- 9 files changed, 1308 insertions(+), 2 deletions(-) create mode 100644 Examples/v2/route-guide/RouteGuide.swift create mode 100644 Examples/v2/route-guide/Subcommands/GetFeature.swift create mode 100644 Examples/v2/route-guide/Subcommands/ListFeatures.swift create mode 100644 Examples/v2/route-guide/Subcommands/RecordRoute.swift create mode 100644 Examples/v2/route-guide/Subcommands/RouteChat.swift create mode 100644 Examples/v2/route-guide/Subcommands/Serve.swift create mode 100644 Examples/v2/route-guide/route_guide_db.json diff --git a/Examples/v2/route-guide/RouteGuide.swift b/Examples/v2/route-guide/RouteGuide.swift new file mode 100644 index 000000000..acdadf17e --- /dev/null +++ b/Examples/v2/route-guide/RouteGuide.swift @@ -0,0 +1,26 @@ +/* + * Copyright 2024, gRPC 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 + * + * http://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 ArgumentParser + +@main +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct RouteGuide: AsyncParsableCommand { + static let configuration = CommandConfiguration( + commandName: "route-guide-v2", + subcommands: [Serve.self, GetFeature.self, ListFeatures.self, RecordRoute.self, RouteChat.self] + ) +} diff --git a/Examples/v2/route-guide/Subcommands/GetFeature.swift b/Examples/v2/route-guide/Subcommands/GetFeature.swift new file mode 100644 index 000000000..696382390 --- /dev/null +++ b/Examples/v2/route-guide/Subcommands/GetFeature.swift @@ -0,0 +1,68 @@ +/* + * Copyright 2024, gRPC 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 + * + * http://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 ArgumentParser +import GRPCHTTP2Transport + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct GetFeature: AsyncParsableCommand { + static let configuration = CommandConfiguration(abstract: "Gets a feature at a given location.") + + @Option(help: "The server's listening port") + var port: Int = 31415 + + @Option( + name: [.customLong("latitude"), .customLong("lat")], + help: "Latitude of the feature to get in E7 format (degrees ⨯ 1e7)" + ) + var latitude: Int32 = 407_838_351 + + @Option( + name: [.customLong("longitude"), .customLong("lon")], + help: "Longitude of the feature to get in E7 format (degrees ⨯ 1e7)" + ) + var longitude: Int32 = -746_143_763 + + func run() async throws { + let transport = try HTTP2ClientTransport.Posix( + target: .ipv4(host: "127.0.0.1", port: self.port) + ) + let client = GRPCClient(transport: transport) + + try await withThrowingDiscardingTaskGroup { group in + group.addTask { + try await client.run() + } + + let routeGuide = Routeguide_RouteGuideClient(wrapping: client) + + let point = Routeguide_Point.with { + $0.latitude = self.latitude + $0.longitude = self.longitude + } + + let feature = try await routeGuide.getFeature(point) + + if feature.name.isEmpty { + print("No feature found at (\(self.latitude), \(self.longitude))") + } else { + print("Found '\(feature.name)' at (\(self.latitude), \(self.longitude))") + } + + client.close() + } + } +} diff --git a/Examples/v2/route-guide/Subcommands/ListFeatures.swift b/Examples/v2/route-guide/Subcommands/ListFeatures.swift new file mode 100644 index 000000000..a1b80d661 --- /dev/null +++ b/Examples/v2/route-guide/Subcommands/ListFeatures.swift @@ -0,0 +1,85 @@ +/* + * Copyright 2024, gRPC 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 + * + * http://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 ArgumentParser +import GRPCHTTP2Transport + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct ListFeatures: AsyncParsableCommand { + static let configuration = CommandConfiguration( + abstract: "List all features within a bounding rectangle." + ) + + @Option(help: "The server's listening port") + var port: Int = 31415 + + @Option( + name: [.customLong("minimum-latitude"), .customLong("min-lat")], + help: "Minimum latitude of the bounding rectangle to search in E7 format." + ) + var minLatitude: Int32 = 400_000_000 + + @Option( + name: [.customLong("maximum-latitude"), .customLong("max-lat")], + help: "Maximum latitude of the bounding rectangle to search in E7 format." + ) + var maxLatitude: Int32 = 420_000_000 + + @Option( + name: [.customLong("minimum-longitude"), .customLong("min-lon")], + help: "Minimum longitude of the bounding rectangle to search in E7 format." + ) + var minLongitude: Int32 = -750_000_000 + + @Option( + name: [.customLong("maximum-longitude"), .customLong("max-lon")], + help: "Maximum longitude of the bounding rectangle to search in E7 format." + ) + var maxLongitude: Int32 = -730_000_000 + + func run() async throws { + let transport = try HTTP2ClientTransport.Posix( + target: .ipv4(host: "127.0.0.1", port: self.port) + ) + let client = GRPCClient(transport: transport) + + try await withThrowingDiscardingTaskGroup { group in + group.addTask { + try await client.run() + } + + let routeGuide = Routeguide_RouteGuideClient(wrapping: client) + let boundingRectangle = Routeguide_Rectangle.with { + $0.lo.latitude = self.minLatitude + $0.hi.latitude = self.maxLatitude + $0.lo.longitude = self.minLongitude + $0.hi.longitude = self.maxLongitude + } + + try await routeGuide.listFeatures(boundingRectangle) { response in + var count = 0 + for try await feature in response.messages { + count += 1 + let (lat, lon) = (feature.location.latitude, feature.location.longitude) + print("(\(count)) \(feature.name) at (\(lat), \(lon))") + } + } + + client.close() + } + + } +} diff --git a/Examples/v2/route-guide/Subcommands/RecordRoute.swift b/Examples/v2/route-guide/Subcommands/RecordRoute.swift new file mode 100644 index 000000000..965fe80e2 --- /dev/null +++ b/Examples/v2/route-guide/Subcommands/RecordRoute.swift @@ -0,0 +1,73 @@ +/* + * Copyright 2024, gRPC 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 + * + * http://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 ArgumentParser +import GRPCHTTP2Transport + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct RecordRoute: AsyncParsableCommand { + static let configuration = CommandConfiguration( + abstract: "Records a route by visiting N randomly selected points and prints a summary of it." + ) + + @Option(help: "The server's listening port") + var port: Int = 31415 + + @Option(help: "The number of places to visit.") + var points: Int = 10 + + func run() async throws { + let transport = try HTTP2ClientTransport.Posix( + target: .ipv4(host: "127.0.0.1", port: self.port) + ) + let client = GRPCClient(transport: transport) + + try await withThrowingDiscardingTaskGroup { group in + group.addTask { + try await client.run() + } + + let routeGuide = Routeguide_RouteGuideClient(wrapping: client) + + // Get all features. + let rectangle = Routeguide_Rectangle.with { + $0.lo.latitude = 400_000_000 + $0.hi.latitude = 420_000_000 + $0.lo.longitude = -750_000_000 + $0.hi.longitude = -730_000_000 + } + let features = try await routeGuide.listFeatures(rectangle) { response in + try await response.messages.reduce(into: []) { $0.append($1) } + } + + // Pick 'N' locations to visit. + let placesToVisit = features.shuffled().map { $0.location }.prefix(self.points) + + // Record a route. + let summary = try await routeGuide.recordRoute { writer in + try await writer.write(contentsOf: placesToVisit) + } + + let text = """ + Visited \(summary.pointCount) points and \(summary.featureCount) features covering \ + a distance \(summary.distance) metres. + """ + print(text) + + client.close() + } + } +} diff --git a/Examples/v2/route-guide/Subcommands/RouteChat.swift b/Examples/v2/route-guide/Subcommands/RouteChat.swift new file mode 100644 index 000000000..b66cc284f --- /dev/null +++ b/Examples/v2/route-guide/Subcommands/RouteChat.swift @@ -0,0 +1,73 @@ +/* + * Copyright 2024, gRPC 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 + * + * http://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 ArgumentParser +import GRPCHTTP2Transport + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct RouteChat: AsyncParsableCommand { + static let configuration = CommandConfiguration( + abstract: """ + Visits a few points and records a note at each, and prints all notes previously recorded at \ + each point. + """ + ) + + @Option(help: "The server's listening port") + var port: Int = 31415 + + func run() async throws { + let transport = try HTTP2ClientTransport.Posix( + target: .ipv4(host: "127.0.0.1", port: self.port) + ) + let client = GRPCClient(transport: transport) + + try await withThrowingDiscardingTaskGroup { group in + group.addTask { + try await client.run() + } + + let routeGuide = Routeguide_RouteGuideClient(wrapping: client) + + try await routeGuide.routeChat { writer in + let notes: [(String, (Int32, Int32))] = [ + ("First message", (0, 0)), + ("Second message", (0, 1)), + ("Third message", (1, 0)), + ("Fourth message", (0, 0)), + ("Fifth message", (1, 0)), + ] + + for (message, (lat, lon)) in notes { + let note = Routeguide_RouteNote.with { + $0.message = message + $0.location.latitude = lat + $0.location.longitude = lon + } + print("Sending note: '\(message) at (\(lat), \(lon))'") + try await writer.write(note) + } + } onResponse: { response in + for try await note in response.messages { + let (lat, lon) = (note.location.latitude, note.location.longitude) + print("Received note: '\(note.message) at (\(lat), \(lon))'") + } + } + + client.close() + } + } +} diff --git a/Examples/v2/route-guide/Subcommands/Serve.swift b/Examples/v2/route-guide/Subcommands/Serve.swift new file mode 100644 index 000000000..9af509502 --- /dev/null +++ b/Examples/v2/route-guide/Subcommands/Serve.swift @@ -0,0 +1,246 @@ +/* + * Copyright 2024, gRPC 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 + * + * http://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 ArgumentParser +import Foundation +import GRPCHTTP2Transport +import GRPCProtobuf +import Synchronization + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct Serve: AsyncParsableCommand { + static let configuration = CommandConfiguration(abstract: "Starts a route-guide server.") + + @Option(help: "The port to listen on") + var port: Int = 31415 + + private func loadFeatures() throws -> [Routeguide_Feature] { + guard let url = Bundle.module.url(forResource: "route_guide_db", withExtension: "json") else { + throw RPCError(code: .internalError, message: "Couldn't find 'route_guide_db.json") + } + + let data = try Data(contentsOf: url) + return try Routeguide_Feature.array(fromJSONUTF8Bytes: data) + } + + func run() async throws { + let features = try self.loadFeatures() + let transport = HTTP2ServerTransport.Posix( + address: .ipv4(host: "127.0.0.1", port: self.port), + config: .defaults(transportSecurity: .plaintext) + ) + + let server = GRPCServer(transport: transport, services: [RouteGuideService(features: features)]) + try await withThrowingDiscardingTaskGroup { group in + group.addTask { try await server.run() } + let address = try await transport.listeningAddress + print("server listening on \(address)") + } + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +struct RouteGuideService { + /// Known features. + private let features: [Routeguide_Feature] + /// Notes recorded by clients. + private let receivedNotes: Notes + + /// A thread-safe store for notes sent by clients. + private final class Notes: Sendable { + private let notes: Mutex<[Routeguide_RouteNote]> + + init() { + self.notes = Mutex([]) + } + + /// Records a note and returns all other notes recorded at the same location. + /// + /// - Parameter receivedNote: A note to record. + /// - Returns: Other notes recorded at the same location. + func recordNote(_ receivedNote: Routeguide_RouteNote) -> [Routeguide_RouteNote] { + return self.notes.withLock { notes in + var notesFromSameLocation: [Routeguide_RouteNote] = [] + for note in notes { + if note.location == receivedNote.location { + notesFromSameLocation.append(note) + } + } + notes.append(receivedNote) + return notesFromSameLocation + } + } + } + + /// Creates a new route guide service. + /// - Parameter features: Known features. + init(features: [Routeguide_Feature]) { + self.features = features + self.receivedNotes = Notes() + } + + /// Returns the first feature found at the given location, if one exists. + private func findFeature(latitude: Int32, longitude: Int32) -> Routeguide_Feature? { + self.features.first { + $0.location.latitude == latitude && $0.location.longitude == longitude + } + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension RouteGuideService: Routeguide_RouteGuide.ServiceProtocol { + func getFeature( + request: ServerRequest.Single + ) async throws -> ServerResponse.Single { + let feature = self.findFeature( + latitude: request.message.latitude, + longitude: request.message.longitude + ) + + if let feature { + return ServerResponse.Single(message: feature) + } else { + // No feature: return a feature with an empty name. + let unknownFeature = Routeguide_Feature.with { + $0.name = "" + $0.location = .with { + $0.latitude = request.message.latitude + $0.longitude = request.message.longitude + } + } + return ServerResponse.Single(message: unknownFeature) + } + } + + func listFeatures( + request: ServerRequest.Single + ) async throws -> ServerResponse.Stream { + return ServerResponse.Stream { writer in + let featuresWithinBounds = self.features.filter { feature in + !feature.name.isEmpty && feature.isContained(by: request.message) + } + + try await writer.write(contentsOf: featuresWithinBounds) + return [:] + } + } + + func recordRoute( + request: ServerRequest.Stream + ) async throws -> ServerResponse.Single { + let startTime = ContinuousClock.now + var pointsVisited = 0 + var featuresVisited = 0 + var distanceTravelled = 0.0 + var previousPoint: Routeguide_Point? = nil + + for try await point in request.messages { + pointsVisited += 1 + + if self.findFeature(latitude: point.latitude, longitude: point.longitude) != nil { + featuresVisited += 1 + } + + if let previousPoint { + distanceTravelled += greatCircleDistance(from: previousPoint, to: point) + } + + previousPoint = point + } + + let duration = startTime.duration(to: .now) + let summary = Routeguide_RouteSummary.with { + $0.pointCount = Int32(pointsVisited) + $0.featureCount = Int32(featuresVisited) + $0.elapsedTime = Int32(duration.components.seconds) + $0.distance = Int32(distanceTravelled) + } + + return ServerResponse.Single(message: summary) + } + + func routeChat( + request: ServerRequest.Stream + ) async throws -> ServerResponse.Stream { + return ServerResponse.Stream { writer in + for try await note in request.messages { + let notes = self.receivedNotes.recordNote(note) + try await writer.write(contentsOf: notes) + } + return [:] + } + } +} + +extension Routeguide_Feature { + func isContained( + by rectangle: Routeguide_Rectangle + ) -> Bool { + return rectangle.lo.latitude <= self.location.latitude + && self.location.latitude <= rectangle.hi.latitude + && rectangle.lo.longitude <= self.location.longitude + && self.location.longitude <= rectangle.hi.longitude + } +} + +private func greatCircleDistance( + from point1: Routeguide_Point, + to point2: Routeguide_Point +) -> Double { + // See https://en.wikipedia.org/wiki/Great-circle_distance + // + // Let λ1 (lambda1) and φ1 (phi1) be the longitude and latitude of point 1. + // Let λ2 (lambda2) and φ2 (phi2) be the longitude and latitude of point 2. + // + // Let Δλ = λ2 - λ1, and Δφ = φ2 - φ1. + // + // The central angle between them, σc (sigmaC) can be computed as: + // + // σc = 2 ⨯ sqrt(sin²(Δφ/2) + cos(φ1) ⨯ cos(φ2) ⨯ sin²(Δλ/2)) + // + // The unit distance (d) between point1 and point2 can then be computed as: + // + // d = 2 ⨯ atan(sqrt(σc), sqrt(1 - σc)) + + let lambda1 = radians(degreesInE7: point1.longitude) + let phi1 = radians(degreesInE7: point1.latitude) + let lambda2 = radians(degreesInE7: point2.longitude) + let phi2 = radians(degreesInE7: point2.latitude) + + // Δλ = λ2 - λ1 + let deltaLambda = lambda2 - lambda1 + // Δφ = φ2 - φ1 + let deltaPhi = phi2 - phi1 + + // sin²(Δφ/2) + let sinHalfDeltaPhiSquared = sin(deltaPhi / 2) * sin(deltaPhi / 2) + // sin²(Δλ/2) + let sinHalfDeltaLambdaSquared = sin(deltaLambda / 2) * sin(deltaLambda / 2) + + // σc = 2 ⨯ sqrt(sin²(Δφ/2) + cos(φ1) ⨯ cos(φ2) ⨯ sin²(Δλ/2)) + let sigmaC = 2 * sqrt(sinHalfDeltaPhiSquared + cos(phi1) * cos(phi2) * sinHalfDeltaLambdaSquared) + + // This is the unit distance, i.e. assumes the circle has a radius of 1. + let unitDistance = 2 * atan2(sqrt(sigmaC), sqrt(1 - sigmaC)) + + // Scale it by the radius of the Earth in meters. + let earthRadius = 6_371_000.0 + return unitDistance * earthRadius +} + +private func radians(degreesInE7 degrees: Int32) -> Double { + return (Double(degrees) / 1e7) * .pi / 180.0 +} diff --git a/Examples/v2/route-guide/route_guide_db.json b/Examples/v2/route-guide/route_guide_db.json new file mode 100644 index 000000000..22e93e313 --- /dev/null +++ b/Examples/v2/route-guide/route_guide_db.json @@ -0,0 +1,702 @@ +[ + { + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" + }, + { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" + }, + { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" + }, + { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" + }, + { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" + }, + { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" + }, + { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" + }, + { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" + }, + { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" + }, + { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" + }, + { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" + }, + { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" + }, + { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" + }, + { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" + }, + { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" + }, + { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" + }, + { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" + }, + { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" + }, + { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" + }, + { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" + }, + { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" + }, + { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" + }, + { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" + }, + { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" + }, + { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" + }, + { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" + }, + { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" + }, + { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" + }, + { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" + }, + { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" + }, + { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" + }, + { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" + }, + { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" + }, + { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" + }, + { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" + }, + { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" + }, + { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" + }, + { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" + }, + { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" + }, + { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" + }, + { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" + }, + { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" + }, + { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" + }, + { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" + }, + { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" + }, + { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" + }, + { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" + }, + { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" + }, + { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" + }, + { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" + }, + { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" + }, + { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" + }, + { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" + }, + { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" + }, + { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" + }, + { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" + }, + { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" + }, + { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" + }, + { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" + }, + { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" + }, + { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" + }, + { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" + }, + { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" + }, + { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" + }, + { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" + }, + { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" + }, + { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" + }, + { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" + }, + { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" + }, + { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" + }, + { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" + }, + { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" + }, + { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" + }, + { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" + }, + { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" + }, + { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" + }, + { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" + }, + { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" + }, + { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" + }, + { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" + }, + { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" + }, + { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" + }, + { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" + }, + { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" + }, + { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" + }, + { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" + }, + { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" + }, + { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" + }, + { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" + }, + { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" + }, + { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" + }, + { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" + }, + { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" + }, + { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" + }, + { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" + }, + { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" + }, + { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" + }, + { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" + }, + { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" + }, + { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" + } +] diff --git a/Package@swift-6.swift b/Package@swift-6.swift index 118db3950..99206ce42 100644 --- a/Package@swift-6.swift +++ b/Package@swift-6.swift @@ -768,6 +768,9 @@ extension Target { .argumentParser, ], path: "Examples/v2/hello-world", + exclude: [ + "HelloWorld.proto" + ], swiftSettings: [ .swiftLanguageMode(.v6), .enableUpcomingFeature("ExistentialAny"), @@ -820,6 +823,26 @@ extension Target { ) } + static var routeGuide_v2: Target { + .executableTarget( + name: "route-guide", + dependencies: [ + .grpcProtobuf, + .grpcHTTP2Transport, + .argumentParser, + ], + path: "Examples/v2/route-guide", + resources: [ + .copy("route_guide_db.json") + ], + swiftSettings: [ + .swiftLanguageMode(.v6), + .enableUpcomingFeature("ExistentialAny"), + .enableUpcomingFeature("InternalImportsByDefault") + ] + ) + } + static var packetCapture: Target { .executableTarget( name: "PacketCapture", @@ -1088,6 +1111,7 @@ let package = Package( // v2 examples .echo_v2, .helloWorld_v2, + .routeGuide_v2, ] ) diff --git a/Protos/generate.sh b/Protos/generate.sh index e35f7e042..6346105b2 100755 --- a/Protos/generate.sh +++ b/Protos/generate.sh @@ -88,7 +88,7 @@ function generate_echo_v2_example { generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Internal" "_V2=true" } -function generate_routeguide_example { +function generate_routeguide_v1_example { local proto="$here/examples/route_guide/route_guide.proto" local output="$root/Examples/v1/RouteGuide/Model" @@ -96,6 +96,14 @@ function generate_routeguide_example { generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Public" } +function generate_routeguide_v2_example { + local proto="$here/examples/route_guide/route_guide.proto" + local output="$root/Examples/v2/route-guide/Generated" + + generate_message "$proto" "$(dirname "$proto")" "$output" "Visibility=Internal" + generate_grpc "$proto" "$(dirname "$proto")" "$output" "Visibility=Internal" "_V2=true" +} + function generate_helloworld_v1_example { local proto="$here/upstream/grpc/examples/helloworld.proto" local output="$root/Examples/v1/HelloWorld/Model" @@ -261,7 +269,8 @@ function generate_health_service { # Examples generate_echo_v1_example generate_echo_v2_example -generate_routeguide_example +generate_routeguide_v1_example +generate_routeguide_v2_example generate_helloworld_v1_example generate_helloworld_v2_example generate_reflection_data_example From ca82b3a605bd93a633773343222be34154dd05c5 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Wed, 21 Aug 2024 17:36:22 +0100 Subject: [PATCH 3/6] fix typo --- Examples/v2/route-guide/RouteGuide.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/v2/route-guide/RouteGuide.swift b/Examples/v2/route-guide/RouteGuide.swift index acdadf17e..d53882726 100644 --- a/Examples/v2/route-guide/RouteGuide.swift +++ b/Examples/v2/route-guide/RouteGuide.swift @@ -20,7 +20,7 @@ import ArgumentParser @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) struct RouteGuide: AsyncParsableCommand { static let configuration = CommandConfiguration( - commandName: "route-guide-v2", + commandName: "route-guide", subcommands: [Serve.self, GetFeature.self, ListFeatures.self, RecordRoute.self, RouteChat.self] ) } From 866d71cc38f4797eb2dc0d1a4c30e1c5d1f2679c Mon Sep 17 00:00:00 2001 From: George Barnett Date: Mon, 2 Sep 2024 15:16:30 +0100 Subject: [PATCH 4/6] regenerate --- Examples/v2/route-guide/Generated/route_guide.pb.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/v2/route-guide/Generated/route_guide.pb.swift b/Examples/v2/route-guide/Generated/route_guide.pb.swift index d5d28f0f9..09892ef83 100644 --- a/Examples/v2/route-guide/Generated/route_guide.pb.swift +++ b/Examples/v2/route-guide/Generated/route_guide.pb.swift @@ -1,5 +1,6 @@ // DO NOT EDIT. // swift-format-ignore-file +// swiftlint:disable all // // Generated by the Swift generator plugin for the protocol buffer compiler. // Source: route_guide.proto @@ -21,7 +22,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -import Foundation import SwiftProtobuf // If the compiler emits an error on this type, it is because this file From e79850683202c25b0ae66da7aab26138a655dcc3 Mon Sep 17 00:00:00 2001 From: George Barnett Date: Mon, 2 Sep 2024 15:25:55 +0100 Subject: [PATCH 5/6] Add config to route guide --- Examples/v2/route-guide/Subcommands/RecordRoute.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/v2/route-guide/Subcommands/RecordRoute.swift b/Examples/v2/route-guide/Subcommands/RecordRoute.swift index 965fe80e2..2482e842a 100644 --- a/Examples/v2/route-guide/Subcommands/RecordRoute.swift +++ b/Examples/v2/route-guide/Subcommands/RecordRoute.swift @@ -31,7 +31,8 @@ struct RecordRoute: AsyncParsableCommand { func run() async throws { let transport = try HTTP2ClientTransport.Posix( - target: .ipv4(host: "127.0.0.1", port: self.port) + target: .ipv4(host: "127.0.0.1", port: self.port), + config: .defaults() ) let client = GRPCClient(transport: transport) From 5116faf2b93703a3c395cf501d4afbee9c42371c Mon Sep 17 00:00:00 2001 From: George Barnett Date: Mon, 2 Sep 2024 15:49:30 +0100 Subject: [PATCH 6/6] add config --- Examples/v2/route-guide/Subcommands/GetFeature.swift | 3 ++- Examples/v2/route-guide/Subcommands/ListFeatures.swift | 3 ++- Examples/v2/route-guide/Subcommands/RouteChat.swift | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Examples/v2/route-guide/Subcommands/GetFeature.swift b/Examples/v2/route-guide/Subcommands/GetFeature.swift index 696382390..a8e56191a 100644 --- a/Examples/v2/route-guide/Subcommands/GetFeature.swift +++ b/Examples/v2/route-guide/Subcommands/GetFeature.swift @@ -38,7 +38,8 @@ struct GetFeature: AsyncParsableCommand { func run() async throws { let transport = try HTTP2ClientTransport.Posix( - target: .ipv4(host: "127.0.0.1", port: self.port) + target: .ipv4(host: "127.0.0.1", port: self.port), + config: .defaults() ) let client = GRPCClient(transport: transport) diff --git a/Examples/v2/route-guide/Subcommands/ListFeatures.swift b/Examples/v2/route-guide/Subcommands/ListFeatures.swift index a1b80d661..4bb33c2c3 100644 --- a/Examples/v2/route-guide/Subcommands/ListFeatures.swift +++ b/Examples/v2/route-guide/Subcommands/ListFeatures.swift @@ -52,7 +52,8 @@ struct ListFeatures: AsyncParsableCommand { func run() async throws { let transport = try HTTP2ClientTransport.Posix( - target: .ipv4(host: "127.0.0.1", port: self.port) + target: .ipv4(host: "127.0.0.1", port: self.port), + config: .defaults() ) let client = GRPCClient(transport: transport) diff --git a/Examples/v2/route-guide/Subcommands/RouteChat.swift b/Examples/v2/route-guide/Subcommands/RouteChat.swift index b66cc284f..55e3be6f9 100644 --- a/Examples/v2/route-guide/Subcommands/RouteChat.swift +++ b/Examples/v2/route-guide/Subcommands/RouteChat.swift @@ -31,7 +31,8 @@ struct RouteChat: AsyncParsableCommand { func run() async throws { let transport = try HTTP2ClientTransport.Posix( - target: .ipv4(host: "127.0.0.1", port: self.port) + target: .ipv4(host: "127.0.0.1", port: self.port), + config: .defaults() ) let client = GRPCClient(transport: transport)