Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignoring path components #81

Open
KunzManuel opened this issue Jun 29, 2023 · 2 comments
Open

Ignoring path components #81

KunzManuel opened this issue Jun 29, 2023 · 2 comments

Comments

@KunzManuel
Copy link

Hello everyone 馃憢

We are currently using URLRouting in our Application.
In our current case we've been facing a problem with the parsing of the path of an URL.

Use case:

The link which will be parsed looks like this:
https://example.de/colors

In some cases this link can have multiple path components. The number of path components is not fixed and we do not know how many additional path components are added to this link (0..n).

Is there any way this can be done. We tried multiple combinations with Skip, Many and Rest but the problem seems to be that the Path component passes one element to the Parser at a time.

The workaround for us would be to implement a custom Path parser which does not pass the path components one by one but the whole path at once. So we can work with the Prefix Parser.
We'd like to know if there is a better way with the given component?

Thank you for having a look at this. 馃憤

Following a code example to represent the problem.

import Foundation
import URLRouting

enum AppRoute {
    case colors
}


let appRouter = OneOf {
    Route(.case(AppRoute.colors)) {
        Scheme("https")
        Host("example.de")
        Path {
            "colors"
        }
    }
    
}

let testURL = URL(string: "https://example.de/colors")!
let testURL2 = URL(string: "https://example.de/colors/foo")!
try appRouter.match(url: testURL) // matches AppRoute.colors
try appRouter.match(url: testURL2) // fails with expected end of input`
@oliverfoggin
Copy link

I am also having this issue. Did you manage to get this working in the end?

@KunzManuel
Copy link
Author

Unfortunately not with the given Parsers.
For me the solution as to write a customer parser which checks for the prefix only and consumes the path.

struct PrefixPath: ParserPrinter {
    @usableFromInline
    var pathPrefix: String

    /// Initializes a prefix path parser.
    /// Validates if a given path starts with the prefix. Path after the prefix will be ignored.
    /// - Parameter pathPrefix: The prefix which will be
    @inlinable
    init(_ pathPrefix: String) {
        self.pathPrefix = pathPrefix
    }

    @inlinable
    func parse(_ input: inout URLRequestData) throws {
        guard input.path.count >= 1 else { throw PrefixPathRoutingError() }
        let path = input.path.joined(separator: "/").lowercased()

        guard path.hasPrefix(pathPrefix.lowercased()) else {
            throw PrefixPathRoutingError()
        }
        input.path = []
    }

    @inlinable
    func print(_: (), into input: inout URLRequestData) {
        input.path = pathPrefix.split(separator: "/")[...]
    }
}

@usableFromInline
struct PrefixPathRoutingError: Error {
    @usableFromInline
    init() {}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants