A few important things needs to get this to be 'right':
1a. Have a way to return a response with a status code.
1b. Use that mechanism in the default catchers.
2. Automatically fill in that code from the #[error] handler.
3. Have a way for a responder to say if responding succeeded.
4. Try next highest ranking route if responding with one handler fails.
Added `error` decorator and `errors` macro.
The current idea is that you can have "catchers" for all valid errors code (in
range [400, 500). At the moment, catchers are just request handlers, and the
decorator expected an empty function signature for the error handler. Obviously,
this is pretty useless. Not sure on what the API should be here. But, progress.
Oh, one more thing: who should handle forwarding a request to a catcher?
Probably not the router. So, the main Rocket should?
Here's the idea: under the `Rocket` namespace should live things critical to
writing simple Rocket apps: Request, Response, Error, etc. Nothing should be
nested more than one level deep. Only items required for more complex things
(implementing uncommon traits, etc.) should be nested one level deep.
This commit is the first attempt at realizing this.
There's something going on with Hyper. When a 303 (see other) response is sent
in response to a POST, the browser does a GET to the location header. Hyper
somehow misreads the method parameter here, resulting in a route failer.
I need to MITM the connection to see exactly what the browser is sending and
what Hyper is receiving to see who's wrong.
Experimented with the new impl specialization features of Rust. They work! But
they're not quite there yet. Specifically, I was able to specialize on
`Responder`, but when trying to remove the macro in `FromParam`, it didn't work.
See https://github.com/rust-lang/rust/issues/31844.
Okay, so, given a URI, we can figure out which route is corresponds to.
Unfortunately, the handler is not yet part of that route, and we're not parsing
the parameters from the path quite yet. But, we're almost there!
At the moment, I simply install the first route I see into the Rocket struct
directly. This is quite terrible. What's worse is that I assume that the Route's
path and handler are static! The handler, actually, does have to be static, but
its response may have whatever (valid) lifetime, though I'm not sure anything
but `static makes sense. I'll think about it.
In any case, the weird `static` restrictions need to be removed, and I need to
think about which lifetimes are safe here. IE: Must all routes be static? Can I
use a closure as a route? (that'd be neat). If so, how do we make that work?
In any case, it's nice to see SOMETHING work. Yay!
Subset of list of changes:
* Split up decorator and macro into their own files.
* Fully parsing the path parameter and verifying against the function's args.
* Actually calling methods to fetch and convert the request parameters.
* Actually calling methods to convert the handler's return type.
* Sketched out more of the Request/Response structures.
Pretty close to having a fully working MVP.
Here's what works so far:
* The `route` decorator checks its inputs correctly. There's a nice utility
for doing this, and it's working quite well at the moment.
* The `route` decorator emits a `route_fn` and a `route_struct`. The `routes`
* macro prepends the path terminator with the route struct prefix. The
* `Rocket` library can read mount information (though not act on it properly
just yet) and launch a server using Hyper.