diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..d86995350b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - '*' + workflow_dispatch: + +jobs: + macos_tests: + runs-on: macos-11 + strategy: + matrix: + xcode: + - "13.2.1" # Swift 5.5 + command: + - test + - benchmarks + steps: + - uses: actions/checkout@v2 + - name: Select Xcode ${{ matrix.xcode }} + run: sudo xcode-select -s /Applications/Xcode_${{ matrix.xcode }}.app + - name: System + run: system_profiler SPHardwareDataType + - name: Run ${{ matrix.command }} + run: make ${{ matrix.command }} + + ubuntu_tests: + strategy: + matrix: + os: [ubuntu-18.04, ubuntu-20.04] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - name: Build + run: swift build + - name: Run tests + run: swift test + + windows_tests: + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v2 + - uses: MaxDesiatov/swift-windows-action@v1 + with: + swift-version: "5.5.1" diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml new file mode 100644 index 0000000000..24a5fda45b --- /dev/null +++ b/.github/workflows/documentation.yml @@ -0,0 +1,112 @@ +# Build and deploy DocC to GitHub pages. Based off of @karwa's work here: +# https://github.com/karwa/swift-url/blob/main/.github/workflows/docs.yml +name: Documentation + +on: + release: + types: + - published + push: + branches: + - main + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout Package + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Download Swift 5.5.1 + run: wget -q https://download.swift.org/swift-5.5.1-release/ubuntu2004/swift-5.5.1-RELEASE/swift-5.5.1-RELEASE-ubuntu20.04.tar.gz + - name: Extract Swift 5.5.1 + run: tar xzf swift-5.5.1-RELEASE-ubuntu20.04.tar.gz + - name: Add Swift toolchain to PATH + run: | + echo "$GITHUB_WORKSPACE/swift-5.5.1-RELEASE-ubuntu20.04/usr/bin" >> $GITHUB_PATH + + - name: Checkout swift-docc + uses: actions/checkout@v2 + with: + repository: apple/swift-docc + ref: main + path: swift-docc + - name: Cache DocC + id: cache-docc + uses: actions/cache@v2 + with: + key: swift-url-docc-build + path: swift-docc/.build + - name: Build swift-docc + if: ${{ !steps.cache-docc.outputs.cache-hit }} + run: | + cd swift-docc; swift build --product docc -c release; cd .. + + - name: Checkout swift-docc-render + uses: actions/checkout@v2 + with: + repository: apple/swift-docc-render + ref: main + path: swift-docc-render + - name: Build swift-docc-render + run: | + cd swift-docc-render; npm install && npm run build; cd .. + + - name: Checkout gh-pages Branch + uses: actions/checkout@v2 + with: + ref: gh-pages + path: docs-out + + - name: Build documentation + run: > + rm -rf docs-out/.git; + rm -rf docs-out/main; + + for tag in $(echo "main"; git tag); + do + echo "⏳ Generating documentation for "$tag" release."; + + if [ -d "docs-out/$tag" ] + then + echo "✅ Documentation for "$tag" already exists."; + else + git checkout "$tag"; + mkdir -p Sources/URLRouting/Documentation.docc; + export DOCC_HTML_DIR="$(pwd)/swift-docc-render/dist"; + + rm -rf .build/symbol-graphs; + mkdir -p .build/symbol-graphs; + swift build \ + --target URLRouting \ + -Xswiftc \ + -emit-symbol-graph \ + -Xswiftc \ + -emit-symbol-graph-dir \ + -Xswiftc \ + .build/symbol-graphs \ + && swift-docc/.build/release/docc convert Sources/URLRouting/Documentation.docc \ + --fallback-display-name URLRouting \ + --fallback-bundle-identifier co.pointfree.URLRouting \ + --fallback-bundle-version 0.0.0 \ + --additional-symbol-graph-dir \ + .build/symbol-graphs \ + --transform-for-static-hosting \ + --hosting-base-path /swift-url-routing/"$tag" \ + --output-path docs-out/"$tag" \ + && echo "✅ Documentation generated for "$tag" release." \ + || echo "⚠️ Documentation skipped for "$tag"."; + fi; + done + + - name: Fix permissions + run: 'sudo chown --recursive $USER docs-out' + - name: Publish documentation to GitHub Pages + uses: JamesIves/github-pages-deploy-action@4.1.7 + with: + branch: gh-pages + folder: docs-out + single-commit: true diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000000..dc82144b9d --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,27 @@ +name: Format + +on: + push: + branches: + - main + +jobs: + swift_format: + name: swift-format + runs-on: macOS-11 + steps: + - uses: actions/checkout@v2 + - name: Xcode Select + run: sudo xcode-select -s /Applications/Xcode_13.0.app + - name: Tap + run: brew tap pointfreeco/formulae + - name: Install + run: brew install Formulae/swift-format@5.5 + - name: Format + run: make format + - uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: Run swift-format + branch: 'main' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..95c4320919 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj +xcuserdata/ diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000..919434a625 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/URLRouting-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/URLRouting-Package.xcscheme new file mode 100644 index 0000000000..32df3f1329 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/URLRouting-Package.xcscheme @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/URLRouting.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/URLRouting.xcscheme new file mode 100644 index 0000000000..5842664bb7 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/URLRouting.xcscheme @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/swift-url-routing-benchmark.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/swift-url-routing-benchmark.xcscheme new file mode 100644 index 0000000000..9d5a155280 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/swift-url-routing-benchmark.xcscheme @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/variadics-generator.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/variadics-generator.xcscheme new file mode 100644 index 0000000000..cf615c488d --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/variadics-generator.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..3baf9dae9f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Point-Free + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..0d82322ba9 --- /dev/null +++ b/Makefile @@ -0,0 +1,44 @@ +PLATFORM_IOS = iOS Simulator,name=iPhone 11 Pro +PLATFORM_MACOS = macOS +PLATFORM_TVOS = tvOS Simulator,name=Apple TV 4K (at 1080p) + +default: test + +benchmarks: + swift run -c release swift-url-routing-benchmark + +test: + xcodebuild test \ + -scheme URLRouting \ + -destination platform="$(PLATFORM_IOS)" + xcodebuild test \ + -scheme URLRouting \ + -destination platform="$(PLATFORM_MACOS)" + xcodebuild test \ + -scheme URLRouting \ + -destination platform="$(PLATFORM_TVOS)" + +test-linux: + docker run \ + --rm \ + -v "$(PWD):$(PWD)" \ + -w "$(PWD)" \ + swift:5.3 \ + bash -c 'make test-swift' + +test-swift: + swift test \ + --enable-test-discovery \ + --parallel + +format: + swift format --in-place --recursive \ + ./Package.swift ./Sources ./Tests + find . -type f -name '*.md' -print0 | xargs -0 perl -pi -e 's/ +$$//' + +generate-variadics: + swift run variadics-generator \ + --generate-path-zips \ + > Sources/URLRouting/Builders/Variadics.swift + +.PHONY: benchmarks format generate-variadics test diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000000..e33450ab6f --- /dev/null +++ b/Package.resolved @@ -0,0 +1,52 @@ +{ + "object": { + "pins": [ + { + "package": "swift-argument-parser", + "repositoryURL": "https://github.com/apple/swift-argument-parser", + "state": { + "branch": null, + "revision": "6b2aa2748a7881eebb9f84fb10c01293e15b52ca", + "version": "0.5.0" + } + }, + { + "package": "Benchmark", + "repositoryURL": "https://github.com/google/swift-benchmark", + "state": { + "branch": null, + "revision": "a0564bf88df5f94eec81348a2f089494c6b28d80", + "version": "0.1.1" + } + }, + { + "package": "swift-case-paths", + "repositoryURL": "https://github.com/pointfreeco/swift-case-paths", + "state": { + "branch": null, + "revision": "ce9c0d897db8a840c39de64caaa9b60119cf4be8", + "version": "0.8.1" + } + }, + { + "package": "swift-parsing", + "repositoryURL": "https://github.com/pointfreeco/swift-parsing", + "state": { + "branch": null, + "revision": "28d32e9ace1c4c43f5e5a177be837a202494c2d5", + "version": "0.9.2" + } + }, + { + "package": "xctest-dynamic-overlay", + "repositoryURL": "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state": { + "branch": null, + "revision": "50a70a9d3583fe228ce672e8923010c8df2deddd", + "version": "0.2.1" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000000..4164f3cab0 --- /dev/null +++ b/Package.swift @@ -0,0 +1,42 @@ +// swift-tools-version: 5.5 + +import PackageDescription + +let package = Package( + name: "URLRouting", + products: [ + .library(name: "URLRouting", targets: ["URLRouting"]) + ], + dependencies: [ + .package(url: "https://github.com/apple/swift-argument-parser", from: "0.5.0"), + .package(url: "https://github.com/pointfreeco/swift-parsing", from: "0.9.2"), + .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "0.2.1"), + .package(name: "Benchmark", url: "https://github.com/google/swift-benchmark", from: "0.1.1"), + ], + targets: [ + .target( + name: "URLRouting", + dependencies: [ + .product(name: "Parsing", package: "swift-parsing"), + .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), + ] + ), + .testTarget( + name: "URLRoutingTests", + dependencies: [ + "URLRouting" + ] + ), + .executableTarget( + name: "swift-url-routing-benchmark", + dependencies: [ + "URLRouting", + .product(name: "Benchmark", package: "Benchmark"), + ] + ), + .executableTarget( + name: "variadics-generator", + dependencies: [.product(name: "ArgumentParser", package: "swift-argument-parser")] + ), + ] +) diff --git a/README.md b/README.md new file mode 100644 index 0000000000..c1802cf275 --- /dev/null +++ b/README.md @@ -0,0 +1,131 @@ +# swift-url-routing + +A bidirectional router with more type safety and less fuss. This library is built with [Parsing][swift-parsing]. + +--- + +* [Motivation](#Motivation) +* [Getting started](#Getting-started) +* [Documentation](#Documentation) +* [License](#License) + +## Learn More + +This library was discussed in an [episode](http://pointfree.co/episodes/ep187-tour-of-parser-printers-url-routing) of [Point-Free](http://pointfree.co), a video series exploring functional programming and the Swift programming and the Swift language, hosted by [Brandon Williams](https://twitter.com/mbrandonw) and [Stephen Celis](https://twitter.com/stephencelis). + + + video poster image + + +## Motivation + +URL routing is a ubiquitous problem in both client-side and server-side applications: + +* Clients, such as iOS applications, need to route URLs for deep-linking, which amounts to picking apart a URL in order to figure out where to navigate the user in the app. +* Servers, such as [Vapor][vapor] applications, also need to pick apart URL requests to figure out what page to serve, but also need to _generate_ valid URLs for linking within the website. + +This library provides URL routing function for both client and server applications, and does so in a composable, type-safe manner. + +## Getting Started + +To use the library you first begin with a domain modeling exercise. You model a route enum that represents each URL you want to recognize in your application, and each case of the enum holds the data you want to extract from the URL. + +For example, if we had screens in our application that represent showing all books, showing a particular book, and searching books, we can model this as an enum: + +```swift +enum AppRoute { + case books + case book(id: Int) + case searchBooks(query: String, count: Int = 10) +} +``` + +Notice that we only encode the data we want to extract from the URL in these cases. There are no details of where this data lives in the URL, such as whether it comes from path parameters, query parameters or POST body data. + +Those details are determined by the router, which can be constructed with the tools shipped in this library. Its purpose is to transform an incoming URL into the `AppRoute` type. For example: + +```swift +import URLRouting + +let appRouter = OneOf { + // GET /books + Route(.case(AppRoute.books))) { + Path { "books" } + } + + // GET /books/:id + Route(.case(AppRoute.books(id:))) { + Path { "books"; Digits() } + } + + // GET /books/search?query=:query&count=:count + Route(.case(AppRoute.searchBooks(query:count:))) { + Path { "books"; "search" } + Query { + Field("query") + Field("count", default: 10) { Digits() } + } + } +} +``` + +This router describes at a high-level how to pick apart the path components, query parameters, and more from a URL in order to transform it into a `AppRoute`. + +Once this router is defined you can use it to implement deep-linking logic in your application. You can implement a single function that accepts a `URL`, use the router's `match` method to transform it into an `AppRoute`, and then switch on the route to handle each deep link destination: + +```swift +func handleDeepLink(url: URL) throws { + switch try appRouter.match(url: url) { + case .books: + // navigate to books screen + + case let .book(id: id): + // navigate to book with id + + case let .searchBooks(query: query, count: count): + // navigate to search screen with query and count + } +} +``` + +This kind of routing is incredibly useful in client side iOS applications, but it can also be used in server-side applications. Even better, it can automatically transform `AppRoute` values back into URL's which is handy for linking to various parts of your website: + +```swift +appRoute.path(for: .searchBooks(query: "Blob Bio")) +// /books/search?query=Blob%20Bio +``` + +```swift +Node.ul( + books.map { book in + .li( + .a( + .href(appRoute.path(for: .book(id: book.id))), + book.title + ) + ) + } +) +``` +```html + +``` + +## Documentation + +The documentation for releases and main are available here: + +* [main][swift-url-routing-docs] +* [0.1.0](https://pointfreeco.github.io/swift-url-routing/0.1.0/documentation/urlrouting) + +## License + +This library is released under the MIT license. See [LICENSE](LICENSE) for details. + +[swift-url-routing-docs]: https://pointfreeco.github.io/swift-url-routing +[swift-parsing]: http://github.com/pointfreeco/swift-parsing +[vapor]: http://vapor.codes diff --git a/Sources/URLRouting/Body.swift b/Sources/URLRouting/Body.swift new file mode 100644 index 0000000000..7c4afacfac --- /dev/null +++ b/Sources/URLRouting/Body.swift @@ -0,0 +1,56 @@ +import Foundation + +/// Parses a request's body using a byte parser. +public struct Body: Parser where Bytes.Input == Data { + @usableFromInline + let bytesParser: Bytes + + @inlinable + public init(@ParserBuilder _ bytesParser: () -> Bytes) { + self.bytesParser = bytesParser() + } + + /// Initializes a body parser from a byte conversion. + /// + /// Useful for parsing a request body in its entirety, for example as a JSON payload. + /// + /// ```swift + /// struct Comment: Codable { + /// var author: String + /// var message: String + /// } + /// + /// Body(.json(Comment.self)) + /// ``` + /// + /// - Parameter bytesConversion: A conversion that transforms bytes into some other type. + @inlinable + public init(_ bytesConversion: C) + where Bytes == Parsers.MapConversion>, C> { + self.bytesParser = Rest().replaceError(with: .init()).map(bytesConversion) + } + + /// Initializes a body parser that parses the body as data in its entirety. + @inlinable + public init() where Bytes == Parsers.ReplaceError> { + self.bytesParser = Rest().replaceError(with: .init()) + } + + @inlinable + public func parse(_ input: inout URLRequestData) throws -> Bytes.Output { + guard var body = input.body + else { throw RoutingError() } + + let output = try self.bytesParser.parse(&body) + input.body = body + + return output + } +} + +extension Body: ParserPrinter where Bytes: ParserPrinter { + @inlinable + public func print(_ output: Bytes.Output, into input: inout URLRequestData) rethrows { + input.body = try self.bytesParser.print(output) + } +} diff --git a/Sources/URLRouting/Builders/Variadics.swift b/Sources/URLRouting/Builders/Variadics.swift new file mode 100644 index 0000000000..9c3875f50c --- /dev/null +++ b/Sources/URLRouting/Builders/Variadics.swift @@ -0,0 +1,10683 @@ +// BEGIN AUTO-GENERATED CONTENT + +public struct PathZipOO: Parser +where + P0.Input == Substring, + P1.Input == Substring +{ + public let p0: P0, p1: P1 + + @inlinable public init(_ p0: P0, _ p1: P1) { + self.p0 = p0 + self.p1 = p1 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output + ) { + guard input.path.count >= 2 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + return (o0, o1) + } +} + +extension PathZipOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1 + ) -> PathZipOO { + PathZipOO(p0, p1) + } +} + +public struct PathZipOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P1.Output == Void +{ + public let p0: P0, p1: P1 + + @inlinable public init(_ p0: P0, _ p1: P1) { + self.p0 = p0 + self.p1 = p1 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output + ) { + guard input.path.count >= 2 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + return (o0) + } +} + +extension PathZipOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1 + ) -> PathZipOV { + PathZipOV(p0, p1) + } +} + +public struct PathZipVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P0.Output == Void +{ + public let p0: P0, p1: P1 + + @inlinable public init(_ p0: P0, _ p1: P1) { + self.p0 = p0 + self.p1 = p1 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output + ) { + guard input.path.count >= 2 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + return (o1) + } +} + +extension PathZipVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P0.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p1.print(output)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1 + ) -> PathZipVO { + PathZipVO(p0, p1) + } +} + +public struct PathZipVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P0.Output == Void, + P1.Output == Void +{ + public let p0: P0, p1: P1 + + @inlinable public init(_ p0: P0, _ p1: P1) { + self.p0 = p0 + self.p1 = p1 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws { + guard input.path.count >= 2 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + return () + } +} + +extension PathZipVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P0.Output == Void, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1 + ) -> PathZipVV { + PathZipVV(p0, p1) + } +} + +public struct PathZipOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2) + } +} + +extension PathZipOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipOOO { + PathZipOOO(p0, p1, p2) + } +} + +public struct PathZipOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o0, o1) + } +} + +extension PathZipOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipOOV { + PathZipOOV(p0, p1, p2) + } +} + +public struct PathZipOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o0, o2) + } +} + +extension PathZipOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipOVO { + PathZipOVO(p0, p1, p2) + } +} + +public struct PathZipOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o0) + } +} + +extension PathZipOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipOVV { + PathZipOVV(p0, p1, p2) + } +} + +public struct PathZipVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P0.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o1, o2) + } +} + +extension PathZipVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P0.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipVOO { + PathZipVOO(p0, p1, p2) + } +} + +public struct PathZipVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P0.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o1) + } +} + +extension PathZipVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P0.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipVOV { + PathZipVOV(p0, p1, p2) + } +} + +public struct PathZipVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P0.Output == Void, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output + ) { + guard input.path.count >= 3 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return (o2) + } +} + +extension PathZipVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P0.Output == Void, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print(output)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipVVO { + PathZipVVO(p0, p1, p2) + } +} + +public struct PathZipVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws { + guard input.path.count >= 3 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + return () + } +} + +extension PathZipVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2 + ) -> PathZipVVV { + PathZipVVV(p0, p1, p2) + } +} + +public struct PathZipOOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3) + } +} + +extension PathZipOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOOOO { + PathZipOOOO(p0, p1, p2, p3) + } +} + +public struct PathZipOOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2) + } +} + +extension PathZipOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOOOV { + PathZipOOOV(p0, p1, p2, p3) + } +} + +public struct PathZipOOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3) + } +} + +extension PathZipOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOOVO { + PathZipOOVO(p0, p1, p2, p3) + } +} + +public struct PathZipOOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o1) + } +} + +extension PathZipOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOOVV { + PathZipOOVV(p0, p1, p2, p3) + } +} + +public struct PathZipOVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3) + } +} + +extension PathZipOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOVOO { + PathZipOVOO(p0, p1, p2, p3) + } +} + +public struct PathZipOVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P1.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o2) + } +} + +extension PathZipOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P1.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOVOV { + PathZipOVOV(p0, p1, p2, p3) + } +} + +public struct PathZipOVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0, o3) + } +} + +extension PathZipOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOVVO { + PathZipOVVO(p0, p1, p2, p3) + } +} + +public struct PathZipOVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o0) + } +} + +extension PathZipOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipOVVV { + PathZipOVVV(p0, p1, p2, p3) + } +} + +public struct PathZipVOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3) + } +} + +extension PathZipVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVOOO { + PathZipVOOO(p0, p1, p2, p3) + } +} + +public struct PathZipVOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o1, o2) + } +} + +extension PathZipVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVOOV { + PathZipVOOV(p0, p1, p2, p3) + } +} + +public struct PathZipVOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o1, o3) + } +} + +extension PathZipVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVOVO { + PathZipVOVO(p0, p1, p2, p3) + } +} + +public struct PathZipVOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o1) + } +} + +extension PathZipVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVOVV { + PathZipVOVV(p0, p1, p2, p3) + } +} + +public struct PathZipVVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o2, o3) + } +} + +extension PathZipVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVVOO { + PathZipVVOO(p0, p1, p2, p3) + } +} + +public struct PathZipVVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o2) + } +} + +extension PathZipVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVVOV { + PathZipVVOV(p0, p1, p2, p3) + } +} + +public struct PathZipVVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output + ) { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return (o3) + } +} + +extension PathZipVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print(output)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVVVO { + PathZipVVVO(p0, p1, p2, p3) + } +} + +public struct PathZipVVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws { + guard input.path.count >= 4 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + return () + } +} + +extension PathZipVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3 + ) -> PathZipVVVV { + PathZipVVVV(p0, p1, p2, p3) + } +} + +public struct PathZipOOOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3, o4) + } +} + +extension PathZipOOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.4)) + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOOOO { + PathZipOOOOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3) + } +} + +extension PathZipOOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOOOV { + PathZipOOOOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o4) + } +} + +extension PathZipOOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOOVO { + PathZipOOOVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2) + } +} + +extension PathZipOOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOOVV { + PathZipOOOVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3, o4) + } +} + +extension PathZipOOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOVOO { + PathZipOOVOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3) + } +} + +extension PathZipOOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOVOV { + PathZipOOVOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o4) + } +} + +extension PathZipOOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOVVO { + PathZipOOVVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o1) + } +} + +extension PathZipOOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOOVVV { + PathZipOOVVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3, o4) + } +} + +extension PathZipOVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVOOO { + PathZipOVOOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3) + } +} + +extension PathZipOVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVOOV { + PathZipOVOOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o4) + } +} + +extension PathZipOVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVOVO { + PathZipOVOVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o2) + } +} + +extension PathZipOVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVOVV { + PathZipOVOVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o3, o4) + } +} + +extension PathZipOVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVVOO { + PathZipOVVOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o3) + } +} + +extension PathZipOVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVVOV { + PathZipOVVOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0, o4) + } +} + +extension PathZipOVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVVVO { + PathZipOVVVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOVVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o0) + } +} + +extension PathZipOVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipOVVVV { + PathZipOVVVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3, o4) + } +} + +extension PathZipVOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOOOO { + PathZipVOOOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3) + } +} + +extension PathZipVOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOOOV { + PathZipVOOOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o4) + } +} + +extension PathZipVOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOOVO { + PathZipVOOVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o2) + } +} + +extension PathZipVOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOOVV { + PathZipVOOVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o3, o4) + } +} + +extension PathZipVOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOVOO { + PathZipVOVOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o3) + } +} + +extension PathZipVOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOVOV { + PathZipVOVOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1, o4) + } +} + +extension PathZipVOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOVVO { + PathZipVOVVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVOVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o1) + } +} + +extension PathZipVOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVOVVV { + PathZipVOVVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVOOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o2, o3, o4) + } +} + +extension PathZipVVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVOOO { + PathZipVVOOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVOOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o2, o3) + } +} + +extension PathZipVVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVOOV { + PathZipVVOOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVOVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o2, o4) + } +} + +extension PathZipVVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVOVO { + PathZipVVOVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVOVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o2) + } +} + +extension PathZipVVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVOVV { + PathZipVVOVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVVOO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output, + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o3, o4) + } +} + +extension PathZipVVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print(output.0)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVVOO { + PathZipVVVOO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVVOV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o3) + } +} + +extension PathZipVVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVVOV { + PathZipVVVOV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVVVO: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P4.Output + ) { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return (o4) + } +} + +extension PathZipVVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print(output)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVVVO { + PathZipVVVVO(p0, p1, p2, p3, p4) + } +} + +public struct PathZipVVVVV: Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws { + guard input.path.count >= 5 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + return () + } +} + +extension PathZipVVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4 + ) -> PathZipVVVVV { + PathZipVVVVV(p0, p1, p2, p3, p4) + } +} + +public struct PathZipOOOOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3, o4, o5) + } +} + +extension PathZipOOOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.5)) + input.path.prepend(try p4.print(output.4)) + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOOOO { + PathZipOOOOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3, o4) + } +} + +extension PathZipOOOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.4)) + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOOOV { + PathZipOOOOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3, o5) + } +} + +extension PathZipOOOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.4)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOOVO { + PathZipOOOOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o3) + } +} + +extension PathZipOOOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.3)) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOOVV { + PathZipOOOOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o4, o5) + } +} + +extension PathZipOOOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.4)) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOVOO { + PathZipOOOVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o4) + } +} + +extension PathZipOOOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOVOV { + PathZipOOOVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2, o5) + } +} + +extension PathZipOOOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOVVO { + PathZipOOOVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOOVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P2.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o2) + } +} + +extension PathZipOOOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.2)) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOOVVV { + PathZipOOOVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3, o4, o5) + } +} + +extension PathZipOOVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.4)) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVOOO { + PathZipOOVOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3, o4) + } +} + +extension PathZipOOVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVOOV { + PathZipOOVOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3, o5) + } +} + +extension PathZipOOVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVOVO { + PathZipOOVOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o3) + } +} + +extension PathZipOOVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVOVV { + PathZipOOVOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o4, o5) + } +} + +extension PathZipOOVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVVOO { + PathZipOOVVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o4) + } +} + +extension PathZipOOVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVVOV { + PathZipOOVVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1, o5) + } +} + +extension PathZipOOVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVVVO { + PathZipOOVVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOOVVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P1.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o1) + } +} + +extension PathZipOOVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.1)) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOOVVVV { + PathZipOOVVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3, o4, o5) + } +} + +extension PathZipOVOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.4)) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOOOO { + PathZipOVOOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3, o4) + } +} + +extension PathZipOVOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOOOV { + PathZipOVOOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3, o5) + } +} + +extension PathZipOVOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOOVO { + PathZipOVOOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o3) + } +} + +extension PathZipOVOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOOVV { + PathZipOVOOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o4, o5) + } +} + +extension PathZipOVOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOVOO { + PathZipOVOVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o4) + } +} + +extension PathZipOVOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOVOV { + PathZipOVOVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2, o5) + } +} + +extension PathZipOVOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOVVO { + PathZipOVOVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVOVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P2.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o2) + } +} + +extension PathZipOVOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVOVVV { + PathZipOVOVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o3, o4, o5) + } +} + +extension PathZipOVVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVOOO { + PathZipOVVOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o3, o4) + } +} + +extension PathZipOVVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVOOV { + PathZipOVVOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o3, o5) + } +} + +extension PathZipOVVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVOVO { + PathZipOVVOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o3) + } +} + +extension PathZipOVVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVOVV { + PathZipOVVOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o4, o5) + } +} + +extension PathZipOVVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVVOO { + PathZipOVVVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o4) + } +} + +extension PathZipOVVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVVOV { + PathZipOVVVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0, o5) + } +} + +extension PathZipOVVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.1)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output.0)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVVVO { + PathZipOVVVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipOVVVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P0.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + let o0 = try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o0) + } +} + +extension PathZipOVVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P0.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print(output)) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipOVVVVV { + PathZipOVVVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3, o4, o5) + } +} + +extension PathZipVOOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.4)) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOOOO { + PathZipVOOOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3, o4) + } +} + +extension PathZipVOOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.3)) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOOOV { + PathZipVOOOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3, o5) + } +} + +extension PathZipVOOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOOVO { + PathZipVOOOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o3) + } +} + +extension PathZipVOOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.2)) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOOVV { + PathZipVOOOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o4, o5) + } +} + +extension PathZipVOOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOVOO { + PathZipVOOVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o4) + } +} + +extension PathZipVOOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOVOV { + PathZipVOOVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2, o5) + } +} + +extension PathZipVOOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOVVO { + PathZipVOOVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOOVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P2.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o2) + } +} + +extension PathZipVOOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.1)) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOOVVV { + PathZipVOOVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o3, o4, o5) + } +} + +extension PathZipVOVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVOOO { + PathZipVOVOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o3, o4) + } +} + +extension PathZipVOVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVOOV { + PathZipVOVOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o3, o5) + } +} + +extension PathZipVOVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVOVO { + PathZipVOVOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o3) + } +} + +extension PathZipVOVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVOVV { + PathZipVOVOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o4, o5) + } +} + +extension PathZipVOVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVVOO { + PathZipVOVVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o4) + } +} + +extension PathZipVOVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVVOV { + PathZipVOVVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1, o5) + } +} + +extension PathZipVOVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.1)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output.0)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVVVO { + PathZipVOVVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVOVVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P1.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + let o1 = try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o1) + } +} + +extension PathZipVOVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P1.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print(output)) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVOVVVV { + PathZipVOVVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o3, o4, o5) + } +} + +extension PathZipVVOOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.3)) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOOOO { + PathZipVVOOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o3, o4) + } +} + +extension PathZipVVOOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.2)) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOOOV { + PathZipVVOOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o3, o5) + } +} + +extension PathZipVVOOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOOVO { + PathZipVVOOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o3) + } +} + +extension PathZipVVOOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.1)) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOOVV { + PathZipVVOOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o4, o5) + } +} + +extension PathZipVVOVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOVOO { + PathZipVVOVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o4) + } +} + +extension PathZipVVOVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOVOV { + PathZipVVOVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2, o5) + } +} + +extension PathZipVVOVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.1)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output.0)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOVVO { + PathZipVVOVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVOVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P2.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + let o2 = try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o2) + } +} + +extension PathZipVVOVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P2.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print(output)) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVOVVV { + PathZipVVOVVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVOOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output, + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o3, o4, o5) + } +} + +extension PathZipVVVOOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output, + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.2)) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print(output.0)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVOOO { + PathZipVVVOOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVOOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output, + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o3, o4) + } +} + +extension PathZipVVVOOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output, + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output.1)) + input.path.prepend(try p3.print(output.0)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVOOV { + PathZipVVVOOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVOVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o3, o5) + } +} + +extension PathZipVVVOVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.1)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output.0)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVOVO { + PathZipVVVOVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVOVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P3.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + let o3 = try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o3) + } +} + +extension PathZipVVVOVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P3.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print(output)) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVOVV { + PathZipVVVOVV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVVOO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P4.Output, + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o4, o5) + } +} + +extension PathZipVVVVOO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void +{ + @inlinable public func print( + _ output: ( + P4.Output, + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output.1)) + input.path.prepend(try p4.print(output.0)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVVOO { + PathZipVVVVOO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVVOV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P4.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + let o4 = try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o4) + } +} + +extension PathZipVVVVOV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + P4.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print(output)) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVVOV { + PathZipVVVVOV(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVVVO: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws -> ( + P5.Output + ) { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + let o5 = try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return (o5) + } +} + +extension PathZipVVVVVO: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void +{ + @inlinable public func print( + _ output: ( + P5.Output + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print(output)) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVVVO { + PathZipVVVVVO(p0, p1, p2, p3, p4, p5) + } +} + +public struct PathZipVVVVVV: + Parser +where + P0.Input == Substring, + P1.Input == Substring, + P2.Input == Substring, + P3.Input == Substring, + P4.Input == Substring, + P5.Input == Substring, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + public let p0: P0, p1: P1, p2: P2, p3: P3, p4: P4, p5: P5 + + @inlinable public init(_ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5) { + self.p0 = p0 + self.p1 = p1 + self.p2 = p2 + self.p3 = p3 + self.p4 = p4 + self.p5 = p5 + } + + @inlinable public func parse(_ input: inout URLRequestData) throws { + guard input.path.count >= 6 else { throw RoutingError() } + try Parse { + p0 + End() + }.parse(input.path.removeFirst()) + try Parse { + p1 + End() + }.parse(input.path.removeFirst()) + try Parse { + p2 + End() + }.parse(input.path.removeFirst()) + try Parse { + p3 + End() + }.parse(input.path.removeFirst()) + try Parse { + p4 + End() + }.parse(input.path.removeFirst()) + try Parse { + p5 + End() + }.parse(input.path.removeFirst()) + return () + } +} + +extension PathZipVVVVVV: ParserPrinter +where + P0: ParserPrinter, + P1: ParserPrinter, + P2: ParserPrinter, + P3: ParserPrinter, + P4: ParserPrinter, + P5: ParserPrinter, + P0.Output == Void, + P1.Output == Void, + P2.Output == Void, + P3.Output == Void, + P4.Output == Void, + P5.Output == Void +{ + @inlinable public func print( + _ output: ( + + ), + into input: inout URLRequestData + ) rethrows { + input.path.prepend(try p5.print()) + input.path.prepend(try p4.print()) + input.path.prepend(try p3.print()) + input.path.prepend(try p2.print()) + input.path.prepend(try p1.print()) + input.path.prepend(try p0.print()) + } +} + +extension PathBuilder { + @inlinable public static func buildBlock( + _ p0: P0, _ p1: P1, _ p2: P2, _ p3: P3, _ p4: P4, _ p5: P5 + ) -> PathZipVVVVVV { + PathZipVVVVVV(p0, p1, p2, p3, p4, p5) + } +} + +// END AUTO-GENERATED CONTENT diff --git a/Sources/URLRouting/Client/Client.swift b/Sources/URLRouting/Client/Client.swift new file mode 100644 index 0000000000..7311545ddf --- /dev/null +++ b/Sources/URLRouting/Client/Client.swift @@ -0,0 +1,273 @@ +import Foundation +import Parsing +import XCTestDynamicOverlay + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +/// A type that can make requests to a server, download the response, and decode the response +/// into a model. +/// +/// You do not typically construct this type directly from its initializer, and instead use the +/// ``live(router:session:)`` static method for creating an API client from a parser-printer, or +/// use the ``failing`` static variable for creating an API client that throws an error when a +/// request is made and then use ``override(_:with:)-1ot4o`` to override certain routes with mocked +/// responses. +public struct URLRoutingClient { + var request: (Route) async throws -> (Data, URLResponse) + + public init(request: @escaping (Route) async throws -> (Data, URLResponse)) { + self.request = request + } + + /// Makes a request to a route. + /// + /// - Parameters: + /// - route: The route to request. + /// - type: The type of value to decode the response into. + /// - decoder: A JSON decoder. + /// - Returns: The decoded value. + @available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *) + public func request( + _ route: Route, + as type: Value.Type = Value.self, + decoder: JSONDecoder = .init() + ) async throws -> (value: Value, response: URLResponse) { + let (data, response) = try await self.request(route) + do { + return (try decoder.decode(type, from: data), response) + } catch { + throw URLRoutingDecodingError(bytes: data, response: response, underlyingError: error) + } + } +} + +public struct URLRoutingDecodingError: Error { + public let bytes: Data + public let response: URLResponse + public let underlyingError: Error +} + +extension URLRoutingClient { + /// Constructs a "live" API client that makes a request to a server using a `URLSession`. + /// + /// This client makes live requests by using the router to turn routes into URL requests, + /// and then using `URLSession` to make the request. + /// + /// - Parameters: + /// - router: A router. + /// - session: A URL session. + /// - Returns: A live API client that makes requests through a URL session. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *) + public static func live(router: R, session: URLSession = .shared) -> Self + where R.Input == URLRequestData, R.Output == Route { + Self { route in + let request = try router.request(for: route) + + #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) + if #available(macOS 12, iOS 15, tvOS 15, watchOS 8, *) { + return try await session.data(for: request) + } + #endif + var dataTask: URLSessionDataTask? + let cancel: () -> Void = { dataTask?.cancel() } + + return try await withTaskCancellationHandler( + handler: { cancel() }, + operation: { + try await withCheckedThrowingContinuation { continuation in + dataTask = session.dataTask(with: request) { data, response, error in + guard + let data = data, + let response = response + else { + continuation.resume(throwing: error ?? URLError(.badServerResponse)) + return + } + + continuation.resume(returning: (data, response)) + } + dataTask?.resume() + } + } + ) + } + } +} + +extension URLRoutingClient { + /// An ``APIClient`` that immediately throws an error when a request is made. + /// + /// This client is useful when testing a feature that uses only a small subset of the available + /// routes in the API client. You can creating a failing API client, and then + /// ``override(_:with:)-1ot4o`` certain routes that return mocked data. + public static var failing: Self { + Self { + let message = """ + Failed to respond to route: \(debugPrint($0)) + + Use '\(Self.self).override' to supply a default response for this route. + """ + XCTFail(message) + throw UnimplementedEndpoint(message: message) + } + } + + /// Constructs a new ``URLRoutingClient`` that returns a certain response for a specified route, + /// and all other routes are passed through to the receiver. + /// + /// - Parameters: + /// - route: The route you want to override. + /// - response: The response to return for the route. + /// - Returns: A new ``URLRoutingClient``. + public func override( + _ route: Route, + with response: @escaping () throws -> Result<(data: Data, response: URLResponse), URLError> + ) -> Self where Route: Equatable { + self.override({ $0 == route }, with: response) + } + + /// Constructs a new ``URLRoutingClient`` that returns a certain response for specific routes, and + /// all other routes are passed through to the receiver. + /// + /// - Parameters: + /// - extract: A closure that determines which routes should be overridden. + /// - response: A closure that determines the response for when a route is overridden. + /// - Returns: A new ``URLRoutingClient``. + public func override( + _ extract: @escaping (Route) -> Value?, + with response: @escaping (Value) throws -> Result<(data: Data, response: URLResponse), URLError> + ) -> Self { + var copy = self + copy.request = { [self] route in + if let value = extract(route) { + return try response(value).get() + } else { + return try await self.request(route) + } + } + return copy + } + + /// Constructs a new ``URLRoutingClient`` that returns a certain response for specific routes, and + /// all other routes are passed through to the receiver. + /// + /// - Parameters: + /// - predicate: A closure that determines if a route matches. + /// - response: A closure that determines the response for when a route matches. + /// - Returns: A new ``URLRoutingClient``. + public func override( + _ predicate: @escaping (Route) -> Bool, + with response: @escaping () throws -> Result<(data: Data, response: URLResponse), URLError> + ) -> Self { + var copy = self + copy.request = { [self] route in + if predicate(route) { + return try response().get() + } else { + return try await self.request(route) + } + } + return copy + } +} + +extension Result where Success == (data: Data, response: URLResponse), Failure == URLError { + /// Constructs a `Result` that represents a HTTP status 200 response. + /// + /// This method is most useful when used in conjunction with + /// ``URLRoutingClient/override(_:with:)-4j1y4`` where you start with a + /// ``URLRoutingClient/failing`` API client and then override certain routes to return mocked + /// responses: + /// + /// ```swift + /// let apiClient = URLRoutingClient.failing + /// .override(SiteRoute.search, with: { .ok(SearchResponse()) }) + /// ``` + /// + /// - Parameters: + /// - value: The value to encode into data for the response. + /// - headerFields: Optional header fields to add to the response. + /// - encoder: The `JSONEncoder` to use to encode the value. + /// - Returns: A result. + public static func ok( + _ value: T, + headerFields: [String: String]? = nil, + encoder: JSONEncoder = .init() + ) throws -> Self { + .success( + ( + try encoder.encode(value), + HTTPURLResponse( + url: .init(string: "/")!, + statusCode: 200, + httpVersion: nil, + headerFields: headerFields + )! + ) + ) + } +} + +private struct UnimplementedEndpoint: LocalizedError { + let message: String + + var errorDescription: String? { + self.message + } +} + +private func debugPrint(_ value: Any) -> String { + func debugTypeHelp(_ type: Any.Type) -> String { + var name = String(reflecting: type) + if let index = name.firstIndex(of: ".") { + name.removeSubrange(...index) + } + return + name + .replacingOccurrences( + of: #"<.+>|\(unknown context at \$[[:xdigit:]]+\)\."#, + with: "", + options: .regularExpression + ) + } + + func debugTupleHelp(_ children: Mirror.Children) -> String { + children.map { label, value in + let childOutput = debugHelp(value) + let label = + label + .map { $0.firstIndex(where: { $0 != "." && !$0.isNumber }) == nil ? "" : "\($0): " } + ?? "" + return "\(label)\(childOutput)" + } + .joined(separator: ", ") + } + + func debugHelp(_ value: Any) -> String { + let mirror = Mirror(reflecting: value) + switch (value, mirror.displayStyle) { + case (_, .enum): + guard let child = mirror.children.first else { + let childOutput = "\(value)" + return childOutput == "\(type(of: value))" ? "" : ".\(childOutput)" + } + let childOutput = debugHelp(child.value) + return ".\(child.label ?? "")\(childOutput.isEmpty ? "" : "(\(childOutput))")" + case (_, .tuple): + return debugTupleHelp(mirror.children) + case (_, .struct): + return "\(debugTypeHelp(mirror.subjectType))(\(debugTupleHelp(mirror.children)))" + case let (value as CustomDebugStringConvertible, _): + return value.debugDescription + case let (value as CustomStringConvertible, _): + return value.description + default: + return "_" + } + } + + return (value as? CustomDebugStringConvertible)?.debugDescription + ?? "\(debugTypeHelp(type(of: value)))\(debugHelp(value))" +} diff --git a/Sources/URLRouting/Cookies.swift b/Sources/URLRouting/Cookies.swift new file mode 100644 index 0000000000..490a8b412f --- /dev/null +++ b/Sources/URLRouting/Cookies.swift @@ -0,0 +1,46 @@ +/// Parses a request's cookies using field parsers. +public struct Cookies: Parser where Parsers.Input == URLRequestData.Fields { + @usableFromInline + let cookieParsers: Parsers + + @inlinable + public init(@ParserBuilder build: () -> Parsers) { + self.cookieParsers = build() + } + + @inlinable + public func parse(_ input: inout URLRequestData) throws -> Parsers.Output { + guard let cookie = input.headers["cookie"] + else { throw RoutingError() } + + var fields: Parsers.Input = cookie.reduce( + into: .init([:], isNameCaseSensitive: true) + ) { fields, field in + guard let cookies = field?.components(separatedBy: "; ") + else { return } + + for cookie in cookies { + let pair = cookie.split(separator: "=", maxSplits: 1, omittingEmptySubsequences: false) + guard pair.count == 2 else { continue } + fields[String(pair[0]), default: []].append(pair[1]) + } + } + + return try self.cookieParsers.parse(&fields) + } +} + +extension Cookies: ParserPrinter where Parsers: ParserPrinter { + @inlinable + public func print(_ output: Parsers.Output, into input: inout URLRequestData) rethrows { + var cookies = URLRequestData.Fields() + try self.cookieParsers.print(output, into: &cookies) + + input.headers["cookie", default: []].prepend( + cookies + .sorted(by: { $0.key < $1.key }) + .flatMap { name, values in values.map { "\(name)=\($0 ?? "")" } } + .joined(separator: "; ")[...] + ) + } +} diff --git a/Sources/URLRouting/Documentation.docc/Articles/GettingStarted.md b/Sources/URLRouting/Documentation.docc/Articles/GettingStarted.md new file mode 100644 index 0000000000..5a8a36a3d0 --- /dev/null +++ b/Sources/URLRouting/Documentation.docc/Articles/GettingStarted.md @@ -0,0 +1,3 @@ +# Getting Started + +Hello diff --git a/Sources/URLRouting/Documentation.docc/URLRouting.md b/Sources/URLRouting/Documentation.docc/URLRouting.md new file mode 100644 index 0000000000..5219a7a2e0 --- /dev/null +++ b/Sources/URLRouting/Documentation.docc/URLRouting.md @@ -0,0 +1,30 @@ +# ``URLRouting`` + +A bidirectional router with more type safety and less fuss. This library is built with [Parsing][swift-parsing]. + +## Additional Resources + +- [GitHub Repo](https://github.com/pointfreeco/swift-parsing) +- [Discussions](https://github.com/pointfreeco/swift-parsing/discussions) +- [Point-Free Videos](https://www.pointfree.co/collections/parsing) + +## Overview + +URL routing is the process of turning a URL request into well-structured data so that you know +where to navigate a user in your application. It is also useful to be able to do the opposite: +turn the well-structured data back into a URL request. + +## Topics + +### Articles + +- ``GettingStarted`` + +## See Also + +The collection of videos from [Point-Free](https://www.pointfree.co) that dive deep into the +development of the Parsing library. + +* [Point-Free Videos](https://www.pointfree.co/collections/parsing) + +[swift-parsing]: http://github.com/pointfreeco/swift-parsing diff --git a/Sources/URLRouting/Exports.swift b/Sources/URLRouting/Exports.swift new file mode 100644 index 0000000000..f5345d8cc3 --- /dev/null +++ b/Sources/URLRouting/Exports.swift @@ -0,0 +1 @@ +@_exported import Parsing diff --git a/Sources/URLRouting/Field.swift b/Sources/URLRouting/Field.swift new file mode 100644 index 0000000000..8ba53ac3a5 --- /dev/null +++ b/Sources/URLRouting/Field.swift @@ -0,0 +1,108 @@ +/// Parses a named field's value with a string parser. +/// +/// Useful for incrementally parsing values from various request fields, including ``Query`` +/// parameters, ``Headers`` and ``Cookies``, and ``FormData``. +/// +/// For example, a search endpoint may include a few query items, which can be specified as fields: +/// +/// ```swift +/// Query { +/// Field("q", .string, default: "") +/// Field("page", default: 1) { +/// Digits() +/// } +/// Field("per_page", default: 20) { +/// Digits() +/// } +/// } +/// ``` +public struct Field: Parser where Value.Input == Substring { + @usableFromInline + let defaultValue: Value.Output? + + @usableFromInline + let name: String + + @usableFromInline + let valueParser: Value + + /// Initializes a named field parser. + /// + /// - Parameters: + /// - name: The name of the field. + /// - defaultValue: A default value if the field is absent. Prefer specifying a default over + /// applying `Parser.replaceError(with:)` if parsing should fail for invalid values. + /// - value: A parser that parses the field's substring value into something more + /// well-structured. + @inlinable + public init( + _ name: String, + default defaultValue: Value.Output? = nil, + @ParserBuilder _ value: () -> Value + ) { + self.defaultValue = defaultValue + self.name = name + self.valueParser = value() + } + + /// Initializes a named field parser. + /// + /// - Parameters: + /// - name: The name of the field. + /// - value: A conversion that transforms the field's substring value into something more + /// well-structured. + /// - defaultValue: A default value if the field is absent. Prefer specifying a default over + /// applying `Parser.replaceError(with:)` if parsing should fail for invalid values. + @inlinable + public init( + _ name: String, + _ value: C, + default defaultValue: Value.Output? = nil + ) where Value == Parsers.MapConversion>, C> { + self.defaultValue = defaultValue + self.name = name + self.valueParser = Rest().replaceError(with: "").map(value) + } + + @inlinable + public init( + _ name: String, + default defaultValue: Value.Output? = nil + ) + where + Value == Parsers.MapConversion< + Parsers.ReplaceError>, Conversions.SubstringToString + > + { + self.defaultValue = defaultValue + self.name = name + self.valueParser = Rest().replaceError(with: "").map(.string) + } + + @inlinable + public func parse(_ input: inout URLRequestData.Fields) throws -> Value.Output { + guard + let wrapped = input[self.name]?.first, + var value = wrapped + else { + guard let defaultValue = self.defaultValue + else { throw RoutingError() } + return defaultValue + } + + let output = try self.valueParser.parse(&value) + input[self.name]?.removeFirst() + if input[self.name]?.isEmpty ?? true { + input[self.name] = nil + } + return output + } +} + +extension Field: ParserPrinter where Value: ParserPrinter { + @inlinable + public func print(_ output: Value.Output, into input: inout URLRequestData.Fields) rethrows { + if let defaultValue = self.defaultValue, isEqual(output, defaultValue) { return } + input[self.name, default: []].prepend(try valueParser.print(output)) + } +} diff --git a/Sources/URLRouting/FormData.swift b/Sources/URLRouting/FormData.swift new file mode 100644 index 0000000000..12d4213687 --- /dev/null +++ b/Sources/URLRouting/FormData.swift @@ -0,0 +1,77 @@ +import Foundation + +/// Parser form-encoded data using field parsers. +public struct FormData: Parser +where FieldParsers.Input == URLRequestData.Fields { + @usableFromInline + let fieldParsers: FieldParsers + + @inlinable + public init(@ParserBuilder build: () -> FieldParsers) { + self.fieldParsers = build() + } + + @inlinable + public func parse(_ input: inout Data) rethrows -> FieldParsers.Output { + var fields: FieldParsers.Input = String(decoding: input, as: UTF8.self) + .split(separator: "&") + .reduce(into: .init([:], isNameCaseSensitive: true)) { fields, field in + let pair = + field + .split(separator: "=", maxSplits: 1, omittingEmptySubsequences: false) + .compactMap { $0.replacingOccurrences(of: "+", with: " ").removingPercentEncoding } + let name = pair[0] + let value = pair.count == 2 ? pair[1][...] : nil + fields[name, default: []].append(value) + } + + let output = try self.fieldParsers.parse(&fields) + + input = .init(encoding: fields) + return output + } +} + +extension FormData: ParserPrinter where FieldParsers: ParserPrinter { + @inlinable + public func print(_ output: FieldParsers.Output, into input: inout Data) rethrows { + var fields = URLRequestData.Fields() + try self.fieldParsers.print(output, into: &fields) + input = .init(encoding: fields) + } +} + +extension Data { + @usableFromInline + init(encoding fields: URLRequestData.Fields) { + self.init( + fields + .sorted(by: { $0.key < $1.key }) + .flatMap { pair -> [String] in + let (name, values) = pair + guard let name = name.addingPercentEncoding(withAllowedCharacters: .urlQueryParamAllowed) + else { return [] } + + return values.compactMap { value in + guard let value = value + else { return name } + + guard + let value = value.addingPercentEncoding(withAllowedCharacters: .urlQueryParamAllowed) + else { return nil } + + return "\(name)=\(value)" + } + } + .joined(separator: "&") + .utf8 + ) + } +} + +extension CharacterSet { + @usableFromInline + static let urlQueryParamAllowed = CharacterSet + .urlQueryAllowed + .subtracting(Self(charactersIn: ":#[]@!$&'()*+,;=")) +} diff --git a/Sources/URLRouting/Headers.swift b/Sources/URLRouting/Headers.swift new file mode 100644 index 0000000000..92490eaa53 --- /dev/null +++ b/Sources/URLRouting/Headers.swift @@ -0,0 +1,23 @@ +/// Parses a request's headers using field parsers. +public struct Headers: Parser +where FieldParsers.Input == URLRequestData.Fields { + @usableFromInline + let fieldParsers: FieldParsers + + @inlinable + public init(@ParserBuilder build: () -> FieldParsers) { + self.fieldParsers = build() + } + + @inlinable + public func parse(_ input: inout URLRequestData) rethrows -> FieldParsers.Output { + try self.fieldParsers.parse(&input.headers) + } +} + +extension Headers: ParserPrinter where FieldParsers: ParserPrinter { + @inlinable + public func print(_ output: FieldParsers.Output, into input: inout URLRequestData) rethrows { + try self.fieldParsers.print(output, into: &input.headers) + } +} diff --git a/Sources/URLRouting/Internal/AnyEquatable.swift b/Sources/URLRouting/Internal/AnyEquatable.swift new file mode 100644 index 0000000000..fa679cf41f --- /dev/null +++ b/Sources/URLRouting/Internal/AnyEquatable.swift @@ -0,0 +1,19 @@ +@usableFromInline +func isEqual(_ lhs: Any, _ rhs: Any) -> Bool { + func open(_: LHS.Type) -> Bool? { + (Box.self as? AnyEquatable.Type)?.isEqual(lhs, rhs) + } + return _openExistential(type(of: lhs), do: open) ?? false +} + +private enum Box {} + +private protocol AnyEquatable { + static func isEqual(_ lhs: Any, _ rhs: Any) -> Bool +} + +extension Box: AnyEquatable where T: Equatable { + fileprivate static func isEqual(_ lhs: Any, _ rhs: Any) -> Bool { + lhs as? T == rhs as? T + } +} diff --git a/Sources/URLRouting/Internal/Breakpoint.swift b/Sources/URLRouting/Internal/Breakpoint.swift new file mode 100644 index 0000000000..f4159e4070 --- /dev/null +++ b/Sources/URLRouting/Internal/Breakpoint.swift @@ -0,0 +1,34 @@ +#if canImport(Darwin) + import Darwin +#endif + +/// Raises a debug breakpoint if a debugger is attached. +@inline(__always) +@usableFromInline +func breakpoint(_ message: @autoclosure () -> String = "") { + #if canImport(Darwin) + // https://github.com/bitstadium/HockeySDK-iOS/blob/c6e8d1e940299bec0c0585b1f7b86baf3b17fc82/Classes/BITHockeyHelper.m#L346-L370 + var name: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()] + var info: kinfo_proc = kinfo_proc() + var info_size = MemoryLayout.size + + let isDebuggerAttached = + sysctl(&name, 4, &info, &info_size, nil, 0) != -1 + && info.kp_proc.p_flag & P_TRACED != 0 + + if isDebuggerAttached { + fputs( + """ + \(message()) + + Caught debug breakpoint. Type "continue" ("c") to resume execution. + + """, + stderr + ) + raise(SIGTRAP) + } + #else + assertionFailure(message()) + #endif +} diff --git a/Sources/URLRouting/Method.swift b/Sources/URLRouting/Method.swift new file mode 100644 index 0000000000..3bda810868 --- /dev/null +++ b/Sources/URLRouting/Method.swift @@ -0,0 +1,57 @@ +/// Parses a request's method. +/// +/// Used to require a particular method at a particular endpoint. +/// +/// ```swift +/// Route(.case(SiteRoute.login)) { +/// Method.post // Only route POST requests +/// ... +/// } +/// ``` +public struct Method: ParserPrinter { + @usableFromInline + let name: String + + /// A parser of GET requests. + /// + /// Recognizes both HEAD and GET HTTP methods. + /// + /// > Note: If you are using a ``Route`` parser you do not need to specify `Method.get` (it is the + /// > default). + public static let get = OneOf { + Self("HEAD") + Self("GET") // NB: Prefer printing "GET" + } + + /// A parser of POST requests. + public static let post = Self("POST") + + /// A parser of PUT requests. + public static let put = Self("PUT") + + /// A parser of PATCH requests. + public static let patch = Self("PATCH") + + /// A parser of DELETE requests. + public static let delete = Self("DELETE") + + /// Initializes a request method parser with a method name. + /// + /// - Parameter name: A method name. + @inlinable + public init(_ name: String) { + self.name = name.uppercased() + } + + @inlinable + public func parse(_ input: inout URLRequestData) throws { + guard let method = input.method else { throw RoutingError() } + try self.name.parse(method) + input.method = nil + } + + @inlinable + public func print(_ output: (), into input: inout URLRequestData) { + input.method = self.name + } +} diff --git a/Sources/URLRouting/Parsing/Parse.swift b/Sources/URLRouting/Parsing/Parse.swift new file mode 100644 index 0000000000..b83cdd77b2 --- /dev/null +++ b/Sources/URLRouting/Parsing/Parse.swift @@ -0,0 +1,10 @@ +import Parsing + +extension Parse { + @inlinable + public init( + _ conversion: Downstream + ) where Parsers == Parsing.Parsers.MapConversion, Downstream> { + self.init { Rest().map(conversion) } + } +} diff --git a/Sources/URLRouting/Parsing/ParserPrinter.swift b/Sources/URLRouting/Parsing/ParserPrinter.swift new file mode 100644 index 0000000000..fd24fdd85a --- /dev/null +++ b/Sources/URLRouting/Parsing/ParserPrinter.swift @@ -0,0 +1,93 @@ +import Foundation + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +extension Parser where Input == URLRequestData { + @inlinable + public func match(request: URLRequest) throws -> Output { + guard let data = URLRequestData(request: request) + else { throw RoutingError() } + return try self.parse(data) + } + + @inlinable + public func match(url: URL) throws -> Output { + guard let data = URLRequestData(url: url) + else { throw RoutingError() } + return try self.parse(data) + } + + @inlinable + public func match(path: String) throws -> Output { + guard let data = URLRequestData(string: path) + else { throw RoutingError() } + return try self.parse(data) + } +} + +extension ParserPrinter where Input == URLRequestData { + @inlinable + public func request(for route: Output) throws -> URLRequest { + guard let request = try URLRequest(data: self.print(route)) + else { throw RoutingError() } + return request + } + + @inlinable + public func url(for route: Output) -> URL { + do { + return try URLComponents(data: self.print(route)).url ?? URL(string: "#route-not-found")! + } catch { + breakpoint( + """ + --- + Could not generate a URL for route: + + \(route) + + The router has not been configured to parse this output and so it cannot print it back \ + into a URL. A '#route-not-found' fragment has been printed instead. + + \(error) + --- + """ + ) + return URL(string: "#route-not-found")! + } + } + + @inlinable + public func path(for route: Output) -> String { + do { + let data = try self.print(route) + var components = URLComponents() + components.path = "/\(data.path.joined(separator: "/"))" + if !data.query.isEmpty { + components.queryItems = data.query + .sorted(by: { $0.key < $1.key }) + .flatMap { name, values in + values.map { URLQueryItem(name: name, value: $0.map(String.init)) } + } + } + return components.string ?? "#route-not-found" + } catch { + breakpoint( + """ + --- + Could not generate a URL for route: + + \(route) + + The router has not been configured to parse this output and so it cannot print it back \ + into a URL. A '#route-not-found' fragment has been printed instead. + + \(error) + --- + """ + ) + return "#route-not-found" + } + } +} diff --git a/Sources/URLRouting/Path.swift b/Sources/URLRouting/Path.swift new file mode 100644 index 0000000000..ca3e9299e6 --- /dev/null +++ b/Sources/URLRouting/Path.swift @@ -0,0 +1,44 @@ +public struct Path: Parser +where ComponentParsers.Input == URLRequestData { + @usableFromInline + let componentParsers: ComponentParsers + + @inlinable + public init(@PathBuilder build: () -> ComponentParsers) { + self.componentParsers = build() + } + + @inlinable + public func parse(_ input: inout URLRequestData) rethrows -> ComponentParsers.Output { + try self.componentParsers.parse(&input) + } +} + +extension Path: ParserPrinter where ComponentParsers: ParserPrinter { + @inlinable + public func print(_ output: ComponentParsers.Output, into input: inout URLRequestData) rethrows { + try self.componentParsers.print(output, into: &input) + } +} + +public struct PathComponent: Parser +where ComponentParser.Input == Substring { + @usableFromInline + let componentParser: ComponentParser + + @usableFromInline + init(_ componentParser: ComponentParser) { + self.componentParser = componentParser + } + + public func parse(_ input: inout URLRequestData) throws -> ComponentParser.Output { + guard input.path.count >= 1 else { throw RoutingError() } + return try self.componentParser.parse(input.path.removeFirst()) + } +} + +extension PathComponent: ParserPrinter where ComponentParser: ParserPrinter { + public func print(_ output: ComponentParser.Output, into input: inout URLRequestData) rethrows { + try input.path.prepend(self.componentParser.print(output)) + } +} diff --git a/Sources/URLRouting/PathBuilder.swift b/Sources/URLRouting/PathBuilder.swift new file mode 100644 index 0000000000..23509999b3 --- /dev/null +++ b/Sources/URLRouting/PathBuilder.swift @@ -0,0 +1,7 @@ +@resultBuilder +public enum PathBuilder { + @inlinable + public static func buildBlock(_ parser: P) -> PathComponent

{ + .init(parser) + } +} diff --git a/Sources/URLRouting/PathEnd.swift b/Sources/URLRouting/PathEnd.swift new file mode 100644 index 0000000000..44bab879c0 --- /dev/null +++ b/Sources/URLRouting/PathEnd.swift @@ -0,0 +1,16 @@ +public struct PathEnd: ParserPrinter { + @inlinable + public init() {} + + @inlinable + public func parse(_ input: inout URLRequestData) throws { + guard var first = input.path.first else { return } + try End().parse(&first) + } + + @inlinable + public func print(_ output: (), into input: inout Input) throws { + guard var first = input.path.first else { return } + try End().print((), into: &first) + } +} diff --git a/Sources/URLRouting/Printing.swift b/Sources/URLRouting/Printing.swift new file mode 100644 index 0000000000..427443ce66 --- /dev/null +++ b/Sources/URLRouting/Printing.swift @@ -0,0 +1,71 @@ +import Foundation +import Parsing + +extension ParserPrinter where Input == URLRequestData { + /// Prepends a router with a base URL for the purpose of printing. + /// + /// Useful for printing absolute URLs to a specific scheme, domain, and path prefix. + /// + /// ```swift + /// let apiRouter = router.baseURL("https://api.pointfree.co/v1") + /// + /// try apiRouter.print(.episodes(.episode(1, .index)) + /// // https://api.pointfree.co/v1/episodes/1 + /// ``` + /// + /// - Parameter urlString: A base URL string. + /// - Returns: A parser-printer that prepends a base URL to whatever this parser-printer prints. + @inlinable + public func baseURL(_ urlString: String) -> BaseURLPrinter { + guard let defaultRequestData = URLRequestData(string: urlString) + else { fatalError("Invalid base URL: \(urlString.debugDescription)") } + return BaseURLPrinter(defaultRequestData: defaultRequestData, upstream: self) + } + + /// Prepends a router with default request data for the purpose of printing. + /// + /// ```swift + /// let authenticatedRouter = router + /// .baseRequestData(.init(headers: ["X-PointFree-Session": ["deadbeef"]])) + /// ``` + /// + /// - Parameter requestData: Default request data to print into. + /// - Returns: A parser-printer that prints into some default request data. + @inlinable + public func baseRequestData(_ requestData: URLRequestData) -> BaseURLPrinter { + BaseURLPrinter(defaultRequestData: requestData, upstream: self) + } +} + +public struct BaseURLPrinter: ParserPrinter +where Upstream.Input == URLRequestData { + @usableFromInline + let defaultRequestData: URLRequestData + + @usableFromInline + let upstream: Upstream + + @usableFromInline + init(defaultRequestData: URLRequestData, upstream: Upstream) { + self.defaultRequestData = defaultRequestData + self.upstream = upstream + } + + @inlinable + public func parse(_ input: inout URLRequestData) rethrows -> Upstream.Output { + try self.upstream.parse(&input) + } + + @inlinable + public func print(_ output: Upstream.Output, into input: inout URLRequestData) rethrows { + try self.upstream.print(output, into: &input) + if let scheme = self.defaultRequestData.scheme { input.scheme = scheme } + if let user = self.defaultRequestData.user { input.user = user } + if let password = self.defaultRequestData.password { input.password = password } + if let host = self.defaultRequestData.host { input.host = host } + if let port = self.defaultRequestData.port { input.port = port } + input.path.prepend(contentsOf: self.defaultRequestData.path) + input.query.fields.merge(self.defaultRequestData.query.fields) { $1 + $0 } + input.headers.fields.merge(self.defaultRequestData.headers.fields) { $1 + $0 } + } +} diff --git a/Sources/URLRouting/Query.swift b/Sources/URLRouting/Query.swift new file mode 100644 index 0000000000..6d0c9c6067 --- /dev/null +++ b/Sources/URLRouting/Query.swift @@ -0,0 +1,37 @@ +/// Parses a request's query using field parsers. +/// +/// For example, a search endpoint may include a few query items, which can be specified as fields: +/// +/// ```swift +/// Query { +/// Field("q", .string, default: "") +/// Field("page", default: 1) { +/// Digits() +/// } +/// Field("per_page", default: 20) { +/// Digits() +/// } +/// } +/// ``` +public struct Query: Parser +where FieldParsers.Input == URLRequestData.Fields { + @usableFromInline + let fieldParsers: FieldParsers + + @inlinable + public init(@ParserBuilder build: () -> FieldParsers) { + self.fieldParsers = build() + } + + @inlinable + public func parse(_ input: inout URLRequestData) rethrows -> FieldParsers.Output { + try self.fieldParsers.parse(&input.query) + } +} + +extension Query: ParserPrinter where FieldParsers: ParserPrinter { + @inlinable + public func print(_ output: FieldParsers.Output, into input: inout URLRequestData) rethrows { + try self.fieldParsers.print(output, into: &input.query) + } +} diff --git a/Sources/URLRouting/Route.swift b/Sources/URLRouting/Route.swift new file mode 100644 index 0000000000..438eb3313a --- /dev/null +++ b/Sources/URLRouting/Route.swift @@ -0,0 +1,83 @@ +/// A parser that attempts to run a number of parsers to accumulate output associated with a +/// particular URL endpoint. +/// +/// `Route` is a domain-specific version of `Parse`, suited to URL request routing. +public struct Route: Parser where Parsers.Input == URLRequestData { + @usableFromInline + let parsers: Parsers + + @inlinable + public init( + _ transform: @escaping (Upstream.Output) -> NewOutput, + @ParserBuilder with build: () -> Upstream + ) + where + Upstream.Input == URLRequestData, + Parsers == Parsing.Parsers.Map + { + self.parsers = build().map(transform) + } + + @_disfavoredOverload + @inlinable + public init( + _ output: NewOutput, + @ParserBuilder with build: () -> Upstream + ) + where + Upstream.Input == URLRequestData, + Parsers == Parsing.Parsers.MapConstant + { + self.parsers = build().map { output } + } + + @inlinable + public init( + _ output: NewOutput + ) + where + Parsers == Parsing.Parsers.MapConstant, NewOutput> + { + self.init(output) { + Always(()) + } + } + + @inlinable + public init( + _ conversion: C, + @ParserBuilder with parsers: () -> P + ) + where + P.Input == URLRequestData, + Parsers == Parsing.Parsers.MapConversion + { + self.parsers = parsers().map(conversion) + } + + @inlinable + public init( + _ conversion: C + ) where Parsers == Parsing.Parsers.MapConversion, C> { + self.init(conversion) { + Always(()) + } + } + + @inlinable + public func parse(_ input: inout URLRequestData) throws -> Parsers.Output { + let output = try self.parsers.parse(&input) + if input.method != nil { + try Method.get.parse(&input) + } + try PathEnd().parse(input) + return output + } +} + +extension Route: ParserPrinter where Parsers: ParserPrinter { + @inlinable + public func print(_ output: Parsers.Output, into input: inout URLRequestData) rethrows { + try self.parsers.print(output, into: &input) + } +} diff --git a/Sources/URLRouting/RoutingError.swift b/Sources/URLRouting/RoutingError.swift new file mode 100644 index 0000000000..0bd558bea9 --- /dev/null +++ b/Sources/URLRouting/RoutingError.swift @@ -0,0 +1,5 @@ +@usableFromInline +struct RoutingError: Error { + @usableFromInline + init() {} +} diff --git a/Sources/URLRouting/URLRequestData+Foundation.swift b/Sources/URLRouting/URLRequestData+Foundation.swift new file mode 100644 index 0000000000..8df438ca14 --- /dev/null +++ b/Sources/URLRouting/URLRequestData+Foundation.swift @@ -0,0 +1,113 @@ +import Foundation + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +extension URLRequestData { + /// Initializes parseable request data from a `URLRequest`. + /// + /// Useful for converting a `URLRequest` from the Foundation framework into parseable + /// ``URLRequestData``. + /// + /// ```swift + /// guard let requestData = URLRequestData(request: urlRequest) + /// else { return } + /// + /// let route = try router.parse(requestData) + /// ``` + /// + /// - Parameter request: A URL request. + public init?(request: URLRequest) { + guard + let url = request.url, + let components = URLComponents(url: url, resolvingAgainstBaseURL: false) + else { return nil } + + self.init( + method: request.httpMethod, + scheme: components.scheme, + user: components.user, + password: components.password, + host: components.host, + port: components.port, + path: components.path, + query: components.queryItems?.reduce(into: [:]) { query, item in + query[item.name, default: []].append(item.value) + } ?? [:], + headers: request.allHTTPHeaderFields?.mapValues { + $0.split(separator: ",", omittingEmptySubsequences: false).map { String($0) } + } ?? [:], + body: request.httpBody + ) + } + + /// Initializes a parseable URL request from a `URL`. + public init?(url: URL) { + self.init(request: URLRequest(url: url)) + } + + /// Initializes a parseable URL request from a URL string. + public init?(string: String) { + guard let url = URL(string: string) + else { return nil } + self.init(url: url) + } +} + +extension URLComponents { + /// Initializes `URLComponents` from parseable/printable request data. + /// + /// Useful for converting ``URLRequestData`` into a `URL`. + /// + /// ```swift + /// let requestData = try router.print(route) + /// guard let urlRequest = URLRequest(data: requestData) + /// else { return } + /// ``` + /// + /// - Parameter data: URL request data. + public init(data: URLRequestData) { + self.init() + self.scheme = data.scheme + self.user = data.user + self.password = data.password + self.host = data.host + self.port = data.port + self.path = "/\(data.path.joined(separator: "/"))" + if !data.query.isEmpty { + self.queryItems = data.query + .sorted(by: { $0.key < $1.key }) + .flatMap { name, values in + values.map { URLQueryItem(name: name, value: $0.map(String.init)) } + } + } + } +} + +extension URLRequest { + /// Initializes a `URLRequest` from parseable/printable request data. + /// + /// Useful for converting ``URLRequestData`` back into a `URLRequest`. + /// + /// ```swift + /// let requestData = try router.print(route) + /// guard let urlRequest = URLRequest(data: requestData) + /// else { return } + /// ``` + /// + /// - Parameter data: URL request data. + public init?(data: URLRequestData) { + guard let url = URLComponents(data: data).url else { return nil } + self.init(url: url) + self.httpMethod = data.method + for (name, values) in data.headers.sorted(by: { $0.key < $1.key }) { + for value in values { + if let value = value { + self.addValue(String(value), forHTTPHeaderField: name) + } + } + } + self.httpBody = data.body.map { Data($0) } + } +} diff --git a/Sources/URLRouting/URLRequestData.swift b/Sources/URLRouting/URLRequestData.swift new file mode 100644 index 0000000000..611a3ffbfd --- /dev/null +++ b/Sources/URLRouting/URLRequestData.swift @@ -0,0 +1,259 @@ +import Foundation + +/// A parseable URL request. +/// +/// Models a URL request in manner that can be incrementally parsed in an efficient way, by storing +/// its various fields as subsequences for parsers to consume. +public struct URLRequestData: Equatable, _EmptyInitializable { + /// The request body. + public var body: Data? + + /// The request headers. + /// + /// Modeled as ``Fields`` for efficient incremental parsing. + /// + /// To incrementally parse from these fields, use the ``Headers`` parser. + public var headers: Fields = .init([:], isNameCaseSensitive: false) + + /// The host subcomponent of the request URL + public var host: String? + + /// An HTTP method, _e.g._ `"GET"` or `"POST"`. + /// + /// To parse, use the ``Method`` parser. + public var method: String? + + /// The password subcomponent of the request URL. + public var password: String? + + /// An array of the request URL's path components. + /// + /// Modeled as an `ArraySlice` of `Substring`s for efficient incremental parsing. + public var path: ArraySlice = [] + + /// The port subcomponent of the request URL. + public var port: Int? + + /// The query subcomponent of the request URL. + /// + /// Modeled as ``Fields`` for efficient incremental parsing. + /// + /// To incrementally parse from these fields, use the ``Headers`` parser. + public var query: Fields = .init([:], isNameCaseSensitive: true) + + /// The scheme, _e.g._ `"https"` or `"http"`. + public var scheme: String? + + /// The user subcomponent of the request URL. + public var user: String? + + /// Initializes an empty URL request. + public init() {} + + /// Initializes a URL request. + /// + /// - Parameters: + /// - method: The HTTP method, _e.g._ `"GET"` or `"POST"`. + /// - scheme: The scheme, _e.g._ `"https"` or `"http"`. + /// - user: The user subcomponent of the request URL. + /// - password: The password subcomponent of the request URL. + /// - host: The host subcomponent of the request URL. + /// - port: The port subcomponent of the request URL. + /// - path: An array of the request URL's path components. + /// - query: The query subcomponent of the request URL. + /// - headers: The request headers. + /// - body: The request body. + @inlinable + public init( + method: String? = nil, + scheme: String? = nil, + user: String? = nil, + password: String? = nil, + host: String? = nil, + port: Int? = nil, + path: String = "", + query: [String: [String?]] = [:], + headers: [String: [String?]] = [:], + body: Data? = nil + ) { + self.body = body + self.headers = .init(headers.mapValues { $0.map { $0?[...] }[...] }, isNameCaseSensitive: false) + self.host = host + self.method = method + self.password = password + self.path = path.split(separator: "/")[...] + self.port = port + self.query = .init(query.mapValues { $0.map { $0?[...] }[...] }, isNameCaseSensitive: true) + self.scheme = scheme + self.user = user + } + + /// A wrapper around a dictionary of strings to array slices of substrings. + /// + /// Used by ``URLRequestData`` to model query parameters and headers in a way that can be + /// efficiently parsed. + public struct Fields { + public var fields: [String: ArraySlice] + + @usableFromInline var isNameCaseSensitive: Bool + + @inlinable + public init( + _ fields: [String: ArraySlice] = [:], + isNameCaseSensitive: Bool + ) { + self.fields = [:] + self.fields.reserveCapacity(fields.count) + self.isNameCaseSensitive = isNameCaseSensitive + for (key, value) in fields { + self[key] = value + } + } + + @inlinable + public subscript(name: String) -> ArraySlice? { + _read { yield self.fields[self.isNameCaseSensitive ? name : name.lowercased()] } + _modify { yield &self.fields[self.isNameCaseSensitive ? name : name.lowercased()] } + } + + @inlinable + public subscript( + name: String, default defaultValue: @autoclosure () -> ArraySlice + ) -> ArraySlice { + _read { + yield self.fields[ + self.isNameCaseSensitive ? name : name.lowercased(), default: defaultValue() + ] + } + _modify { + yield &self.fields[ + self.isNameCaseSensitive ? name : name.lowercased(), default: defaultValue() + ] + } + } + } +} + +extension URLRequestData: Codable { + @inlinable + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.init( + method: try container.decodeIfPresent(String.self, forKey: .method), + scheme: try container.decodeIfPresent(String.self, forKey: .scheme), + user: try container.decodeIfPresent(String.self, forKey: .user), + password: try container.decodeIfPresent(String.self, forKey: .password), + host: try container.decodeIfPresent(String.self, forKey: .host), + port: try container.decodeIfPresent(Int.self, forKey: .port), + path: try container.decodeIfPresent(String.self, forKey: .path) ?? "", + query: try container.decodeIfPresent([String: [String?]].self, forKey: .query) ?? [:], + headers: try container.decodeIfPresent([String: [String?]].self, forKey: .headers) ?? [:], + body: try container.decodeIfPresent(Data.self, forKey: .body) + ) + } + + @inlinable + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encodeIfPresent(self.body.map(Array.init), forKey: .body) + if !self.headers.isEmpty { + try container.encode( + self.headers.fields.mapValues { $0.map { $0.map(String.init) } }, + forKey: .headers + ) + } + try container.encodeIfPresent(self.host, forKey: .host) + try container.encodeIfPresent(self.method, forKey: .method) + try container.encodeIfPresent(self.password, forKey: .password) + if !self.path.isEmpty { try container.encode(self.path.joined(separator: "/"), forKey: .path) } + try container.encodeIfPresent(self.port, forKey: .port) + if !self.query.isEmpty { + try container.encode( + self.query.fields.mapValues { $0.map { $0.map(String.init) } }, + forKey: .query + ) + } + try container.encodeIfPresent(self.scheme, forKey: .scheme) + try container.encodeIfPresent(self.user, forKey: .user) + } + + @usableFromInline + enum CodingKeys: CodingKey { + case body + case headers + case host + case method + case password + case path + case port + case query + case scheme + case user + } +} + +extension URLRequestData: Hashable { + @inlinable + public func hash(into hasher: inout Hasher) { + hasher.combine(self.body) + hasher.combine(self.method) + hasher.combine(self.headers) + hasher.combine(self.host) + hasher.combine(self.password) + hasher.combine(self.path) + hasher.combine(self.port) + hasher.combine(self.query) + hasher.combine(self.scheme) + hasher.combine(self.user) + } +} + +extension URLRequestData.Fields: Collection { + public typealias Element = Dictionary>.Element + public typealias Index = Dictionary>.Index + + @inlinable + public var startIndex: Index { + self.fields.startIndex + } + + @inlinable + public var endIndex: Index { + self.fields.endIndex + } + + @inlinable + public subscript(position: Index) -> Element { + self.fields[position] + } + + @inlinable + public func index(after i: Index) -> Index { + self.fields.index(after: i) + } +} + +extension URLRequestData.Fields: ExpressibleByDictionaryLiteral { + @inlinable + public init(dictionaryLiteral elements: (String, ArraySlice)...) { + self.init(.init(elements) { $0 + $1 }, isNameCaseSensitive: true) + } +} + +extension URLRequestData.Fields: Equatable { + @inlinable + public static func == (lhs: Self, rhs: Self) -> Bool { + guard lhs.count == rhs.count else { return false } + for key in lhs.fields.keys { + guard lhs[key] == rhs[key] else { return false } + } + return true + } +} + +extension URLRequestData.Fields: Hashable { + @inlinable + public func hash(into hasher: inout Hasher) { + hasher.combine(self.fields) + } +} diff --git a/Sources/swift-url-routing-benchmark/Common/Benchmarking.swift b/Sources/swift-url-routing-benchmark/Common/Benchmarking.swift new file mode 100644 index 0000000000..52dbdc1aa1 --- /dev/null +++ b/Sources/swift-url-routing-benchmark/Common/Benchmarking.swift @@ -0,0 +1,46 @@ +import Benchmark + +extension BenchmarkSuite { + func benchmark( + _ name: String, + run: @escaping () throws -> Void, + setUp: @escaping () -> Void = {}, + tearDown: @escaping () -> Void + ) { + self.register( + benchmark: Benchmarking(name: name, run: run, setUp: setUp, tearDown: tearDown) + ) + } +} + +struct Benchmarking: AnyBenchmark { + let name: String + let settings: [BenchmarkSetting] = [] + private let _run: () throws -> Void + private let _setUp: () -> Void + private let _tearDown: () -> Void + + init( + name: String, + run: @escaping () throws -> Void, + setUp: @escaping () -> Void = {}, + tearDown: @escaping () -> Void = {} + ) { + self.name = name + self._run = run + self._setUp = setUp + self._tearDown = tearDown + } + + func setUp() { + self._setUp() + } + + func run(_ state: inout BenchmarkState) throws { + try self._run() + } + + func tearDown() { + self._tearDown() + } +} diff --git a/Sources/swift-url-routing-benchmark/Routing.swift b/Sources/swift-url-routing-benchmark/Routing.swift new file mode 100644 index 0000000000..228cd8c685 --- /dev/null +++ b/Sources/swift-url-routing-benchmark/Routing.swift @@ -0,0 +1,124 @@ +import Benchmark +import Foundation +import Parsing +import URLRouting + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +/// This benchmark demonstrates how you can build a URL request router that can transform an input +/// request into a more well-structured data type, such as an enum. We build a router that can +/// recognize one of 5 routes for a website. +let routingSuite = BenchmarkSuite(name: "Routing") { suite in + if #available(macOS 10.13, *) { + #if compiler(>=5.5) + enum AppRoute: Equatable { + case home + case contactUs + case episodes(EpisodesRoute) + } + enum EpisodesRoute: Equatable { + case index + case episode(id: Int, route: EpisodeRoute) + } + enum EpisodeRoute: Equatable { + case show + case comments(CommentsRoute) + } + enum CommentsRoute: Equatable { + case post(Comment) + case show(count: Int) + } + struct Comment: Codable, Equatable { + let commenter: String + let message: String + } + + let encoder = JSONEncoder() + encoder.outputFormatting = .sortedKeys + + let commentsRouter = OneOf { + Route(.case(CommentsRoute.post)) { + Method.post + Body(.json(Comment.self, encoder: encoder)) + } + + Route(.case(CommentsRoute.show)) { + Query { + Field("count", default: 10) { Digits() } + } + } + } + + let episodeRouter = OneOf { + Route(EpisodeRoute.show) + + Route(.case(EpisodeRoute.comments)) { + Path { From(.utf8) { "comments".utf8 } } + + commentsRouter + } + } + + let episodesRouter = OneOf { + Route(EpisodesRoute.index) + + Route(.case(EpisodesRoute.episode)) { + Path { Digits() } + + episodeRouter + } + } + + let router = OneOf { + Route(AppRoute.home) + + Route(AppRoute.contactUs) { + Path { From(.utf8) { "contact-us".utf8 } } + } + + Route(.case(AppRoute.episodes)) { + Path { From(.utf8) { "episodes".utf8 } } + + episodesRouter + } + } + + let requests = [ + URLRequestData(), + URLRequestData(path: "/contact-us"), + URLRequestData(path: "/episodes"), + URLRequestData(path: "/episodes/1"), + URLRequestData(path: "/episodes/1/comments"), + URLRequestData(path: "/episodes/1/comments", query: ["count": ["20"]]), + URLRequestData( + method: "POST", + path: "/episodes/1/comments", + body: .init(#"{"commenter":"Blob","message":"Hi!"}"#.utf8) + ), + ] + + var output: [AppRoute]! + var expectedOutput: [AppRoute] = [ + .home, + .contactUs, + .episodes(.index), + .episodes(.episode(id: 1, route: .show)), + .episodes(.episode(id: 1, route: .comments(.show(count: 10)))), + .episodes(.episode(id: 1, route: .comments(.show(count: 20)))), + .episodes( + .episode(id: 1, route: .comments(.post(.init(commenter: "Blob", message: "Hi!"))))), + ] + suite.benchmark("Parser") { + output = try requests.map { + var input = $0 + return try router.parse(&input) + } + } tearDown: { + precondition(output == expectedOutput) + precondition(requests == output.map { try! router.print($0) }) + } + #endif + } +} diff --git a/Sources/swift-url-routing-benchmark/main.swift b/Sources/swift-url-routing-benchmark/main.swift new file mode 100644 index 0000000000..b07b10dcd8 --- /dev/null +++ b/Sources/swift-url-routing-benchmark/main.swift @@ -0,0 +1,9 @@ +import Benchmark +import Parsing + +Benchmark.main( + [ + defaultBenchmarkSuite, + routingSuite, + ] +) diff --git a/Sources/variadics-generator/VariadicsGenerator.swift b/Sources/variadics-generator/VariadicsGenerator.swift new file mode 100644 index 0000000000..c53eb03b85 --- /dev/null +++ b/Sources/variadics-generator/VariadicsGenerator.swift @@ -0,0 +1,370 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2021 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import ArgumentParser + +struct Permutation { + let arity: Int + // 1 -> + // 0 -> where P.Output == Void + let bits: Int64 + + func isCaptureless(at index: Int) -> Bool { + bits & (1 << (-index + arity - 1)) != 0 + } + + var hasCaptureless: Bool { + bits != 0 + } + + var identifier: String { + var result = "" + for i in 0.. Permutation? { + guard counter & (1 << arity) == 0 else { + return nil + } + defer { counter += 1 } + return Permutation(arity: arity, bits: counter) + } + } + + public func makeIterator() -> Iterator { + Iterator(arity: arity) + } +} + +func output(_ content: String) { + print(content, terminator: "") +} + +func outputForEach( + _ elements: C, separator: String, _ content: (C.Element) -> String +) { + for i in elements.indices { + output(content(elements[i])) + if elements.index(after: i) != elements.endIndex { + output(separator) + } + } +} + +struct VariadicsGenerator: ParsableCommand { + @Flag(help: "Generate `Zip's") + var generateZips = false + + @Flag(help: "Generate `OneOf's") + var generateOneOfs = false + + @Flag(help: "Generate `PathZip's") + var generatePathZips = false + + func run() throws { + output("// BEGIN AUTO-GENERATED CONTENT\n\n") + + if self.generateZips { + for arity in 2...6 { + emitZipDeclarations(arity: arity) + } + } + + if self.generateOneOfs { + for arity in 2...10 { + emitOneOfDeclaration(arity: arity) + } + } + + if self.generatePathZips { + for arity in 2...6 { + emitPathZipDeclarations(arity: arity) + } + } + + output("// END AUTO-GENERATED CONTENT\n") + } + + func emitZipDeclarations(arity: Int) { + for permutation in Permutations(arity: arity) { + // Emit type declaration. + let typeName = "Zip\(permutation.identifier)" + output("extension ParserBuilder {\n public struct \(typeName)<") + outputForEach(0..: Parser\n where\n ") + outputForEach(Array(zip(0.. P\(permutation.captureIndices[0]).Output ") + default: + output("-> (\n") + outputForEach(permutation.captureIndices, separator: ",\n") { " P\($0).Output" } + output("\n ) ") + } + output("{\n do {\n ") + outputForEach(0..(\n ") + outputForEach(0.. ParserBuilder.\(typeName)<") + outputForEach(0.. {\n") + output(" ParserBuilder.\(typeName)(") + outputForEach(0..: Parser\n where\n ") + outputForEach(Array(zip(0.. P0.Output {") + output("\n let original = input\n ") + outputForEach(0..(\n ") + outputForEach(0.. OneOfBuilder.\(typeName)<") + outputForEach(0.. {\n") + output(" OneOfBuilder.\(typeName)(") + outputForEach(0..: Parser\nwhere\n ") + outputForEach(0.. (\n") + outputForEach(permutation.captureIndices, separator: ",\n") { " P\($0).Output" } + output("\n ) {\n guard input.path.count >= \(arity) else { throw RoutingError() }") + output("\n ") + outputForEach(0..(\n ") + outputForEach(0.. \(typeName)<") + outputForEach(0.. {\n") + output(" \(typeName)(") + outputForEach(0.. input:1:2 + 1 | /123 + | ^ expected "about-us" + | ^ expected "contact-us" + | ^ expected end of input + | ^ expected "users" + """, + "\(error)" + ) + } + } +} diff --git a/Tests/URLRoutingTests/URLRoutingTests.swift b/Tests/URLRoutingTests/URLRoutingTests.swift new file mode 100644 index 0000000000..85eea0c606 --- /dev/null +++ b/Tests/URLRoutingTests/URLRoutingTests.swift @@ -0,0 +1,169 @@ +import Parsing +import URLRouting +import XCTest + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +class URLRoutingTests: XCTestCase { + func testMethod() { + XCTAssertNoThrow(try Method.post.parse(URLRequestData(method: "POST"))) + XCTAssertEqual(try Method.post.print(), URLRequestData(method: "POST")) + } + + func testPath() { + XCTAssertEqual(123, try Path { Int.parser() }.parse(URLRequestData(path: "/123"))) + XCTAssertThrowsError(try Path { Int.parser() }.parse(URLRequestData(path: "/123-foo"))) { + error in + XCTAssertEqual( + """ + error: unexpected input + --> input:1:5 + 1 | /123-foo + | ^ expected end of input + """, + "\(error)" + ) + } + } + + func testFormData() throws { + let p = Body { + FormData { + Field("name", .string) + Field("age") { Int.parser() } + } + } + + var request = URLRequestData(body: .init("name=Blob&age=42&debug=1".utf8)) + let (name, age) = try p.parse(&request) + XCTAssertEqual("Blob", name) + XCTAssertEqual(42, age) + XCTAssertEqual("debug=1", request.body.map { String(decoding: $0, as: UTF8.self) }) + } + + func testHeaders() throws { + let p = Headers { + Field("X-Haha", .string) + } + + var req = URLRequest(url: URL(string: "/")!) + req.addValue("Hello", forHTTPHeaderField: "X-Haha") + req.addValue("Blob", forHTTPHeaderField: "X-Haha") + var request = URLRequestData(request: req)! + + let name = try p.parse(&request) + XCTAssertEqual("Hello", name) + XCTAssertEqual(["X-Haha": ["Blob"]], request.headers) + } + + func testQuery() throws { + let p = Query { + Field("name") + Field("age") { Int.parser() } + } + + var request = URLRequestData(string: "/?name=Blob&age=42&debug=1")! + let (name, age) = try p.parse(&request) + XCTAssertEqual("Blob", name) + XCTAssertEqual(42, age) + XCTAssertEqual(["debug": ["1"]], request.query) + } + + func testQueryDefault() throws { + let p = Query { + Field("page", default: 1) { + Int.parser() + } + } + + var request = URLRequestData(string: "/")! + let page = try p.parse(&request) + XCTAssertEqual(1, page) + XCTAssertEqual([:], request.query) + + XCTAssertEqual( + try p.print(10), + URLRequestData(query: ["page": ["10"]]) + ) + XCTAssertEqual( + try p.print(1), + URLRequestData(query: [:]) + ) + } + + func testCookies() throws { + struct Session: Equatable { + var userId: Int + var isAdmin: Bool + } + + let p = Cookies /*(.destructure(Session.init(userId:isAdmin:)))*/ { + Field("userId") { Int.parser() } + Field("isAdmin") { Bool.parser() } + } + .map(.memberwise(Session.init(userId:isAdmin:))) + + var request = URLRequestData(headers: ["cookie": ["userId=42; isAdmin=true"]]) + XCTAssertEqual( + Session(userId: 42, isAdmin: true), + try p.parse(&request) + ) + XCTAssertEqual( + URLRequestData(headers: ["cookie": ["isAdmin=true; userId=42"]]), + try p.print(Session(userId: 42, isAdmin: true)) + ) + } + + func testJSONCookies() { + struct Session: Codable, Equatable { + var userId: Int + } + + let p = Cookies { + Field("pf_session", .utf8.data.json(Session.self)) + } + + var request = URLRequestData(headers: ["cookie": [#"pf_session={"userId":42}; foo=bar"#]]) + XCTAssertEqual( + Session(userId: 42), + try p.parse(&request) + ) + XCTAssertEqual( + URLRequestData(headers: ["cookie": [#"pf_session={"userId":42}"#]]), + try p.print(Session(userId: 42)) + ) + } + + func testBaseURL() throws { + enum AppRoute { case home, episodes } + + let router = OneOf { + Route(AppRoute.home) + Route(AppRoute.episodes) { + Path { "episodes" } + } + } + + XCTAssertEqual( + "https://api.pointfree.co/v1/episodes?token=deadbeef", + URLRequest( + data: + try router + .baseURL("https://api.pointfree.co/v1?token=deadbeef") + .print(.episodes) + )?.url?.absoluteString + ) + + XCTAssertEqual( + "http://localhost:8080/v1/episodes?token=deadbeef", + URLRequest( + data: + try router + .baseURL("http://localhost:8080/v1?token=deadbeef") + .print(.episodes) + )?.url?.absoluteString + ) + } +}