如何编写一个简单的返回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],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,)`

那是为什么?

解决方法

一种解决方案是对所有回复调用 .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 可以让您一次只使用一种实现该特征的类型,因为您的函数只能有一种返回类型。