Какой единственный тип может ссылаться на hyper HttpConnector и HttpsConnector?

#rust #hyper

#Ржавчина #hyper

Вопрос:

Hyper HttpConnector и hyper_tls HttpsConnector явно реализуют общую черту (или черты). Я изучил их реализации и не смог подобрать правильный тип (или псевдоним), который позволил бы мне передавать экземпляры любой структуры функции, как в программе ниже. Похоже, что Tower::Service<Url> это правильная черта, но я не смог найти правильный ответ и действительно мог бы воспользоваться помощью.

 use hyper::{client::connect::HttpConnector, service::Service, Uri};
use hyper_tls::HttpsConnector;

// What type should param c have here for this program to compile?
fn with_connector(c: ????) {}

fn main() {
    with_connector(HttpConnector::new());
    with_connector(HttpsConnector::new());
}
  

Соответствующие реализации для:

HttpConnector

HttpsConnector

 [dependencies]
hyper = "0.13"
hyper-tls = "0.4.3"
  

Вариант использования заключается в том, что я пишу собственный соединитель, который будет содержать экземпляр любого из них в качестве делегата. Заранее спасибо.

Комментарии:

1. Он использует tower_service::Service underneath, но он реэкспортируется как hyper::service::Service , так что, может быть, использовать это?

2. Проблема, с которой я сталкиваюсь, связана с дженериками и связанными типами для этой функции сервиса, это довольно безумно. Я не знаю, как указать тип, чтобы охватить оба HttpConnector и HttpsConnector .

3. Что вы пробовали, что не работает?

4. Я нашел исправление, которое нравится компилятору. Смотрите решение этого вопроса. Это немного некрасиво и не очевидно, но я изучаю Rust и, возможно, это мое незнание. Спасибо за вашу помощь.

Ответ №1:

Я смог решить эту проблему, скопировав определения универсального типа, общие для обоих соединителей. На мой взгляд, результат все еще безумно уродлив: трудно поверить, что кто-то мог придумать это без копирования / вставки, как я. Но, может быть, у кого-то, кто хорошо знаком с различными задействованными функциями, не возникнет проблем?

 use hyper::{client::connect::HttpConnector, service::Service, Uri};
use hyper_tls::HttpsConnector;
use tokio::io::{AsyncRead, AsyncWrite};

type BoxError = Box<dyn std::error::Error   Send   Sync>;

fn with_connector<T>(conn: T)
where
    T: Service<Uri>,
    T::Response: AsyncRead   AsyncWrite   Send   Unpin,
    T::Future: Send   'static,
    T::Error: Into<BoxError>,
{
    // do something with conn
}

fn main() {
    let http = HttpConnector::new();
    with_connector(http);

    let https = HttpsConnector::new();
    with_connector(https);
}
  
 [dependencies]
hyper = "0.13"
hyper-tls = "0.4.3"
tokio = { version = "0.2", features = ["full"] }