Re:Pencil: A Microframework Inspired by Flask for Rust
by TheHydroImpulse on Tuesday March 08, 2016 @03:16PM
(#11248231)
There's probably some opportunity to use custom annotations in Rust to achieve the same thing.
#[route("/foobar")]
fn user(_: &mut Request) -> PencilResult {
// ...
}
However, procedural macros are unstable, but Rust is able to do amazing things with macros.
Re:Pencil: A Microframework Inspired by Flask for Rust
by fredsir on Tuesday March 08, 2016 @04:36PM
(#11248890)
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?
Re:Pencil: A Microframework Inspired by Flask for Rust
by TheHydroImpulse on Tuesday March 08, 2016 @04:58PM
(#11249087)
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 {
// ...
}
Re:Pencil: A Microframework Inspired by Flask for Rust
by fredsir on Wednesday March 09, 2016 @03:26AM
(#11251668)
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?
Re:Pencil: A Microframework Inspired by Flask for Rust
by stormcrowsx on Tuesday March 08, 2016 @03:18PM
(#11248246)
I'm a huge fan of flask but I actually prefer the approach of not using decorators. Without decorators its easy to see all the paths in one area and they get type-checked in rust.
Re:Pencil: A Microframework Inspired by Flask for Rust
by zanny on Tuesday March 08, 2016 @05:50PM
(#11249427)
There is a language plugin for pythonic decorators in Rust:
Re:Pencil: A Microframework Inspired by Flask for Rust
by Manishearth on Wednesday March 09, 2016 @02:56AM
(#11251549)
You actually can use pythonish decorators in Rust, I wrote a proof of concept library for that: https://github.com/manishearth/rust-adorn (it's not really intended to be used, but if folks want to use it I'm willing to clean it up)
I don't use Rust, but your code examples look great! I understand that Rust has less opportunity for "magic" to clean things up (for example, in Python you can use a decorator to specify a route for a function), but otherwise it looks very clear. Awesome work!