Hacker News new | past | comments | ask | show | jobs | submit login

I know very little Rust, but I was actually looking at how this could be done in Rust some time ago, but I didn't get anything working. All the routes (e.g. /foobar and accompanying function) needs to be collected by the "router" somehow which begs for a global route-container that the route macro (like Flasks route decorator) would need to add routes to, similar to how it is done is Flask, and, well, yeah, I couldn't find a rusty way to do it.

Bearing in mind that macros er unstable, can this be done in Rust, and if so, what would the process be?




There are a few different ways one could achieve this. The first options would be to generate a struct:

    struct RouteUser {
        route: &'static str,
        f: fn(_: &mut Request) -> PencilResult
    }
Then given

    #[route("/user")]
    fn user(_: &mut Request) -> PencilResult {}
You would hijack the `user` function to return an instance of the struct.

    fn user() -> RouteUser {
        // The actual function the user wrote:
        fn user(_: &mut Request) -> PencilResult {
            // ...
        }

        RouteUser {
            // Generated from the annotation argument
            route: "/user",
            f: user
        }
    }
There is a difference between item decorators (`#[foobar]`) and regular procedural macros and I'm not completely sure if you could in-fact significantly change the given function. I haven't touched procedural macros in a while.

To use the above route, you would simply have a `Route` trait perhaps.

    trait Route {}
And implement it for each generated struct:

    impl Route for RouteUser {}
Then you could use the route as

    app.route(user());
Which could be defined as

    fn route<R>(r: R) where R: Route {
        // ...
    }


That seems like a good approach, although one thing is missing: when you use the route-decorator in Flask, the route is registered to the app object "via magic", whereas in your example, you still have to register it manually (`app.route(user())`). Now, I am partial to liking registering manually, like in your example and in Pencil itself, since that's clearer than having a lot of routes spread around in a whole lot of files that are magically registered, but just for the kicks, would it be possible to not having to manually register the route to the app object?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: