Iron 框架如何将修饰符元组应用于 Response::with?

How does the Iron framework apply a tuple of modifiers to Response::with?

我正在查看 Response::with() 的 Iron 源代码,试图了解它如何将元组作为修饰符应用于响应。

据我了解,修饰符只是一个构建器对象,它接收对当前上下文 (self) 的引用,并将您希望构建的对象作为参数(只要您实现modify 函数)。

假设我们有以下代码:

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)))
}

通过文档挖掘,我可以看到 Response::with() 在 Iron 中的实现如下:

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)
}

我正在努力了解我的对象元组是如何转换为修饰符的?我希望看到一个 foreach 可能迭代每个修饰符,但在这里我只看到一个集合操作。

有人可以在这里解释执行顺序并揭示实际发生的事情吗?

有趣的问题!我们再看看函数签名:

fn with<M: Modifier<Response>>(m: M) -> Response

这意味着 with 只接受一个实现 Modifier<Response> 的参数。那么接下来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。例如,让我们看一下这个实现:

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);
    }
}

这为每个大小为 3 的元组实现了特征,其中元素也实现了 Modifier。而modify的实现只是调用每个元组元素的modify-实现;这是您要搜索的 foreach