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

The router should take a string and a function handling the request #2

Closed
bkolobara opened this issue May 11, 2022 · 1 comment
Closed

Comments

@bkolobara
Copy link
Contributor

bkolobara commented May 11, 2022

The string part is straight forward, but the handler part will need to be a bit different in lunatic than in other Rust web frameworks. Axum for example uses a concept of Extractors.

We can't copy this approach, because lunatic can't capture arbitrary closures in rust, only fn functions. We still can pass in non-capturing closures and they will be correctly coerced into functions. However, we can't use the type system to implement traits for fn() functions. To implement the extractor approach we need to be able to do it for functions with different numbers of incoming arguments. E.g.:

fn main() {
    // This doesn't work in rust!!!
    // error[E0277]: the trait bound `fn(()) {handler}: Function` is not satisfied
    router_add("/", handler);
}

fn router_add<H>(route: &str, handler: H)
where
    H: Function,
{
    // Implementation ...
}

fn handler(empty_extractor: ()) {
// Implementation
}

trait Function {}

impl Function for fn() {}
impl Function for fn(_x: ()) {}

We can make this compile but need to change the router_add call to:

router_add("/", handler as fn(()));

What is not great. I'm not sure why the function is not casted by rust into the correct type, but I don't see any effort going on in fixing this. The general recommendation is just to use the Fn*() traits instead, that we can't because we need non-capturing guarantees. And for a bunch of other reasons, we can't determine if the closure is zero-sized (non-capturing), so there is no workaround for this.

Solution

I would just for now stick to having one Request argument that every handler gets, instead of this fancy extractor tricks. E.g.

fn handler(request: Request) {
// Implementation
}

Then the Request can be used to access all the data that would be "extracted" through the extractor.

@bkolobara bkolobara mentioned this issue May 11, 2022
8 tasks
@bkolobara bkolobara changed the title The router should take a string and a function handling the request. The router should take a string and a function handling the request May 11, 2022
@bkolobara
Copy link
Contributor Author

This is not true anymore.

@bkolobara bkolobara closed this as not planned Won't fix, can't repro, duplicate, stale Jun 14, 2022
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

1 participant