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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(unboxed_closures): allow unboxed closures for handlers and error handlers #197

Merged
merged 3 commits into from
Apr 26, 2015

Conversation

Ryman
Copy link
Member

@Ryman Ryman commented Apr 23, 2015

This is a bit of a compromise, allowing unboxed closures to be used for handlers but not for Middleware, while also making the routing a bit less flexible for the moment (can only take unboxed closures and not a Middleware, so you can't have a Router dispatch to another Middleware without wrapping a closure).

The second commit shows an alternative that I encountered while refactoring. If we deem macros acceptable in the time being we could follow that approach, as we maintain flexibility with only a minor syntactic wart. I favor this approach, but wanted to show how the example usage could look without any macros, which is the current state of the PR. Whenever rust-lang/rust#24680 is fixed, we should then be able to depreciate the macro and the user code should be very easy to update middleware! { |req, res| "foo" } becomes |_, res| res.send("foo").

Another alternative is to use Fn(..) as the bound everywhere in future when implementing unboxed closures for a type becomes stable, then the Middleware trait will become redundant and we could implement Fn(..) for Router and such. This approach doesn't help us with the current 1.0 feature-set though.

@Ryman
Copy link
Member Author

Ryman commented Apr 23, 2015

Some example usage:

Macro-less version where router is bounded by Fn instead of Middleware

let visits = AtomicUsize::new(0);
router.get("/", move |_, response|
    response.send(format!("{}", visits.fetch_add(1, Relaxed)))
);

// but unable to do something such as:
router.get("/other", SomeMiddleware);

Retaining the macros which now can use an unboxed closure under the hood, everything sticks with Middleware bounds.

let visits = AtomicUsize::new(0);
router.get("/", middleware! { |_req, _res| format!("{}", visits.fetch_add(1, Relaxed)) });

// can also still do this
router.get("/other", SomeMiddleware);

@cburgdorf
Copy link
Member

I think a router that doesn't accept a Middleware anymore isn't a good compromise for now.

However, your other attempt looks pretty cool.

let visits = AtomicUsize::new(0);
router.get("/", middleware! { |_req, _res| format!("{}", visits.fetch_add(1, Relaxed)) });

// can also still do this
router.get("/other", SomeMiddleware);

This seems to be a good compromise as it allows closure usage with just a little syntactic bloat (the macro). And as rust gets better over time one will just be able to drop the macro and keep the closure as it is. 👍

Ryman added a commit that referenced this pull request Apr 26, 2015
feat(unboxed_closures): allow unboxed closures via middleware! macro
@Ryman Ryman merged commit 7b59496 into nickel-org:master Apr 26, 2015
@bodokaiser
Copy link

Hi,

I still get the error from #136 when trying to compile these two files.

Any ideas?

@Ryman
Copy link
Member Author

Ryman commented May 19, 2015

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

Successfully merging this pull request may close these issues.

3 participants