I am looking into the Iron source code for Response::with()
, trying to understand how it applies a tuple as modifiers to the response.
As I understand, a modifier is simply a builder object, taking in a reference to the current context (self
) and taking the object you wish to build on as a parameter (as long as you implement the modify
function).
Assuming we have the following code:
use iron::modifiers::Header;
fn hello_world(_: &mut Request) -> IronResult<Response> {
let string = get_file_as_string("./public/index.html");
let content_type = Header(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![])));
Ok(Response::with((status::Ok, string, content_type)))
}
Digging through the docs, I can see the implementation of Response::with()
in Iron is as follows:
pub fn new() -> Response {
Response {
status: None, // Start with no response code.
body: None, // Start with no body.
headers: Headers::new(),
extensions: TypeMap::new()
}
}
/// Construct a Response with the specified modifier pre-applied.
pub fn with<M: Modifier<Response>>(m: M) -> Response {
Response::new().set(m)
}
I'm struggling to see how my tuple of objects are translated into modifiers? I'd expect to see a foreach potentially iterating over each modifier, but here I simply see a set operation.
Could somebody explain the order to execution here and uncover what is actually happening?
Interesting question! Let's look at the function signature again:
fn with<M: Modifier<Response>>(m: M) -> Response
This means that with
accepts exactly one argument that implements Modifier<Response>
. So next we could look up what types do implement the trait Modifier
. In the documentation we see that it's not only implemented for String
or Status
, but for tuple types, too! Those implementations are written in this file. For example, let's look at this impl:
impl<X, M1, M2, M3> Modifier<X> for (M1, M2, M3)
where M1: Modifier<X>,
M2: Modifier<X>,
M3: Modifier<X>
{
fn modify(self, x: &mut X) {
self.0.modify(x);
self.1.modify(x);
self.2.modify(x);
}
}
This implements the trait for every tuple of size 3 which elements also implement Modifier
. And the implementation of modify
is just to call the modify
-implementation of each tuple element; this is the foreach you were searching for.