Reputation: 28107
An example from actix-web is as follows:
use actix_web::{web, App, Responder, HttpServer};
async fn index() -> impl Responder {
"Hello world!"
}
#[actix_rt::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().service(
web::scope("/app").route("/index.html", web::get().to(index)),
)
})
.bind("127.0.0.1:8088")?
.run()
.await
}
My question is around how the statement to(index)
works in Rust.
Looking at the source code for to
we see:
pub fn to<F, T, R, U>(mut self, handler: F) -> Self
where
F: Factory<T, R, U>,
// --- snip
Where Factory
is defined as:
pub trait Factory<T, R, O>: Clone + 'static
where
R: Future<Output = O>,
O: Responder,
{
fn call(&self, param: T) -> R;
}
What is the mechanism by which the function async fn index() -> impl Responder
gets converted to Factory<T, R, O>
?
Upvotes: 11
Views: 200
Reputation: 98398
There is an implementation of the trait just after your snippet:
impl<F, R, O> Factory<(), R, O> for F
where
F: Fn() -> R + Clone + 'static,
R: Future<Output = O>,
O: Responder,
{
fn call(&self, _: ()) -> R {
(self)()
}
}
This can be read as: if a type F
implements Fn() -> Future<Output = impl Responder> + ...
then it also implements Factory<(), _, _>
.
And an async fn
is syntactic sugar for a function which returns a Future
of some sort (and can use .await
internally), so async fn index() -> impl Responder
implements Fn() -> impl Future<Output = impl Responder>
so it also implements Factory<(), _, _>
.
Upvotes: 12