Git Product home page Git Product logo

funrouter's Introduction

FunRouter

Functional & type-safe URL routing example for Functional Swift Conference 2016.

There are following route types available.

  • Route1 (struct, function-based)
  • Route2 (enum, optimizable)

Example

Assume typealias Route<Value> = RouteN<Value> (N = 1, 2).

/// Parses "/Hello/{city}/{year}".
let route: Route<(String, Int)> =
    curry { ($1, $2) } <^> match("Hello") <*> string() <*> int()
    
// or, more fancy flipped way:
// let route =
//    /"Hello" </> string() </> int() <&!> flipCurry { ($1, $2) }

let value1 = route.run(["Hello", "Budapest", "2016"])
expect(value1?.0) == "Budapest"
expect(value1?.1) == 2016

let value2 = route.run(["Ya", "tu", "sabes"])
expect(value2).to(beNil())

More complex routing

enum Sitemap {
    case foo(Int)       // "/R/foo/{Int}"
    case bar(Double)    // "/R/bar/{Double}"
    case baz(String)    // "/R/baz/{String}"
    case fooBar         // "/R/foo/bar"
    case notFound
}

let route: Route<Sitemap> =
    match("R")
        *> choice([
            match("foo") *> int() <&> Sitemap.foo,
            match("bar") *> double() <&> Sitemap.bar,
            match("baz") *> string() <&> Sitemap.baz,
            match("foo") *> match("bar") *> pure(Sitemap.fooBar),
        ])
    <|> pure(Sitemap.notFound)
    
expect(route.run(["R", "foo", "123"])) == .foo(123)
expect(route.run(["R", "bar", "4.5"])) == .bar(4.5)
expect(route.run(["R", "baz", "xyz"])) == .baz("xyz")
expect(route.run(["R", "foo", "bar"])) == .fooBar
expect(route.run(["R", "foo", "xxx"])) == .notFound

Optimization

For Route2<Value>, you can call optimize() so that:

// Before optimization (duplicated `match("foo")`)
let naiveRoute: Route<Sitemap> =
    match("R")
        *> choice([
            match("foo") *> int() <&> Sitemap.foo,
            match("bar") *> double() <&> Sitemap.bar,
            match("baz") *> string() <&> Sitemap.baz,
            match("foo") *> match("bar") *> pure(Sitemap.fooBar)
        ])

// After optimization
let optimizedRoute = optimize(naiveRoute)

will have an optimized structure as:

naiveRoute = .match("R", .choice([
    .match("foo", .capture(int)),
    .match("bar", .capture(double)),
    .match("baz", .capture(string)),
    .match("foo", .match("bar", .term(fooBar)))
]))

optimizedRoute = .match("R", .choice([
    .match("bar", .capture(double)),
    .match("baz", .capture(string)),
    .match("foo", .choice([
        .capture(int),
        .match("bar", .term(fooBar))
    ]))
]))

References

License

MIT

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.