I'm trying to wrap my head around the actix framework, but I don't understand what's going on with the generic types on some of the functions I need to call.
impl<F, I, S, B> HttpServer<F, I, S, B>
where
F: Fn() -> I + Send + Clone + 'static,
I: IntoServiceFactory<S>,
S: ServiceFactory<Config = AppConfig, Request = Request>,
S::Error: Into<Error> + 'static,
S::InitError: fmt::Debug,
S::Response: Into<Response<B>> + 'static,
<S::Service as Service>::Future: 'static,
B: MessageBody + 'static,
{
What do those S:: types mean? What are they referencing? Why does this one, <S::Service as Service>::Future: 'static, have angle brackets?
I've looked through "the book" and rust by example, but I can't find any reference to what's happening here.
They’re referring to and placing bounds on associated types. So, in addition to S implementing the ServiceFactory trait, the Error type defined in S’s ServiceFactory implementation must implement Into<Error>+'static, etc.
The angle brackets are there to refer to an associated type of an associated type:
S::Service is the Service type defined in S’s ServiceFactory implementation, and
<S::Service as Service>::Future is the Future type defined in S::Service’s implementation of the Service trait.
The fully-qualified form is <Type as Trait>::AssocType, but this can be shortened to Type::AssocType when the compiler can infer the correct Trait. In this case, there’s only one trait that S is known to implement (ServiceFactory), so it can use the short form.