Черта std :: convert :: From <String>не реализована для hyper :: body :: Body - PullRequest
0 голосов
/ 11 июля 2020
lazy_static::lazy_static! {
    static ref file_data: String = fs::read_to_string("static/login.html").expect("unable to read from static/login.html");
}

#[tokio::main]
async fn main() {
    // code omitted
    let login = warp::path("login").map(move || warp::reply::html(file_data));
    // code omitted
}

Ошибка компиляции:

error[E0277]: the trait bound `hyper::body::body::Body: std::convert::From<file_data>` is not satisfied
   --> src/main.rs:45:49
    |
45  |     let login = warp::path("login").map(move || warp::reply::html(file_data));
    |                                                 ^^^^^^^^^^^^^^^^^ the trait `std::convert::From<file_data>` is not implemented for `hyper::body::body::Body`
    | 
   ::: /home/ichi/.cargo/registry/src/github.com-1ecc6299db9ec823/warp-0.2.3/src/reply.rs:170:11
    |
170 |     Body: From<T>,
    |           ------- required by this bound in `warp::reply::html`
    |
    = help: the following implementations were found:
              <hyper::body::body::Body as std::convert::From<&'static [u8]>>
              <hyper::body::body::Body as std::convert::From<&'static str>>
              <hyper::body::body::Body as std::convert::From<bytes::bytes::Bytes>>
              <hyper::body::body::Body as std::convert::From<std::borrow::Cow<'static, [u8]>>>
            and 4 others

Я пытаюсь передать String закрытию. Согласно документации , From<String> реализуется для hyper::body::Body, а file_data имеет тип String. Так почему я получаю эту ошибку?

Ответы [ 2 ]

2 голосов
/ 11 июля 2020

From lazy_static

Для заданного static ref NAME: TYPE = EXPR; макрос генерирует уникальный тип, реализующий Deref<TYPE>, и сохраняет его в состоянии c с имя NAME. (Атрибуты присоединяются к этому типу.)

То есть тип переменной не TYPE!

Вот почему вы видите ошибка

the trait `std::convert::From<file_data>` is not implemented for `hyper::body::body::Body`
                              ^^^^^^^^^

Вероятно, вам больше повезет с явным разыменованием или клонированием глобальной переменной: warp::reply::html(&*file_data) или warp::reply::html(file_data.clone()).

2 голосов
/ 11 июля 2020

Проблема здесь в том, что lazy_static создает тип оболочки, который ссылается на ваши данные, а hyper не знает, как с этим обращаться. Вы можете использовать file_data.clone(), чтобы клонировать данные, на которые ссылаются, и построить из них тело, но в этом случае на самом деле есть более простой метод. Поскольку ваша строка имеет фиксированное значение и Body реализует From<&'static str>, вам вообще не нужны выделенные в куче String или lazy_static: вы можете использовать следующий код, который просто использует фрагмент постоянной строки, который можно использовать напрямую.

const FILE_DATA: &str = "test";

#[tokio::main]
async fn main() {
    // code omitted
    let login = warp::path("login").map(move || warp::reply::html(FILE_DATA));
    // code omitted
}
...