Как написать простой обработчик деформации, возвращающий json или html?

Имею следующее:

use warp::Filter;

pub struct Router {}

impl Router {
    pub async fn handle(
        &self,
    ) -> std::result::Result<impl warp::Reply, warp::Rejection> {

        let uri = "/path";

        match uri {
            "/metrics-list" => {
                let empty : Vec<u8> = Vec::new();
                Ok(warp::reply::json(&empty))
            }

            "/metrics-ips" => {
                let empty : Vec<u8> = Vec::new();
                Ok(warp::reply::json(&empty))
            }

            &_ => {
                Err(warp::reject::reject())
            }
        }
    }
}

#[tokio::main]
pub async fn main() {
    let r = Router {};

    let handler = warp::path("/").map(|| r.handle());

    warp::serve(handler);
    // .run(([0, 0, 0, 0], 3000))
    // .await;
}

Но даже в этом упрощенном примере я получаю ошибку:

error[E0277]: the trait bound `impl warp::Future: warp::Reply` is not satisfied
  --> src/main.rs:41:17
   |
41 |     warp::serve(handler);
   |                 ^^^^^^^ the trait `warp::Reply` is not implemented for `impl warp::Future`
   |
  ::: $HOME/.cargo/registry/src/github.com-1ecc6299db9ec823/warp-0.2.5/src/server.rs:26:17
   |
26 |     F::Extract: Reply,
   |                 ----- required by this bound in `warp::serve`
   |
   = note: required because of the requirements on the impl of `warp::Reply` for `(impl warp::Future,)`

Это почему?


person Patryk    schedule 02.10.2020    source источник


Ответы (1)


Одно из решений - вызывать .into_response() во всех ваших ответах, а затем изменять тип возвращаемого значения с std::result::Result<impl warp::Reply, warp::Rejection> на std::result::Result<warp::reply::Response, warp::Rejection>.

pub async fn handle(
        &self,
    ) -> std::result::Result<warp::reply::Response, warp::Rejection> {

        let uri = "/path";

        match uri {
            "/metrics-list" => {
                let empty : Vec<u8> = Vec::new();
                Ok(warp::reply::json(&empty).into_response())
            }

            "/metrics-ips" => {
                let empty : Vec<u8> = Vec::new();
                Ok(warp::reply::json(&empty).into_response())
            }

            &_ => {
                Err(warp::reject::reject().into_response())
            }
        }
    }

Причина в том, что, если я правильно понимаю, наличие impl Trait в вашем возвращаемом типе позволяет вам использовать только один тип, который реализует эту черту сразу, поскольку ваша функция может иметь только один возвращаемый тип.

person mirosval    schedule 02.02.2021