错误:类型参数`D`必须用作某些本地类型的类型参数

时间:2016-02-12 13:26:40

标签: mongodb rust nickel

我正在使用与MongoDB的Nickel.rs来构建RESTful api。 我想为类型Responder实现通用mongodb::error::Result<Option<bson::Document>>

这是我根据Responder找到的示例编写的实现:

impl<D> Responder<D> for Result<Option<Document>> {

    fn respond<'a>(self, mut response: Response<'a, D>) -> MiddlewareResult<'a, D> {
        response.set(MediaType::Json);

        match self {
            Ok(Some(doc))=>{
                ApiResponse{data: Bson::Document(doc).to_json()}.to_json()
            },
            Ok(None)=>{
                response.set(StatusCode::NotFound);
                ApiError{error: "Not found".to_string()}.to_json()
            },
            Err(e)=>{
                response.set(StatusCode::InternalServerError);
                ApiError{error: format!("{}",e)}.to_json()
            }

        }
    }
}

我收到以下错误:

  

错误:类型参数D必须用作某些类型参数   本地类型(例如MyStruct<T>);只有当前定义的特征   crate可以用于类型参数[E0210]

我跑了rustc --explain E0210进行解释,如果我的理解是正确的,我需要提供一个特征D作为impl<D>的类型参数,但我不明白哪个特征提供。

我尝试了impl<D: =()>但是产生了同样的错误。

2 个答案:

答案 0 :(得分:4)

当您实施特征时,either the trait or the type you are implementing it for must be defined in the same crate。在您不是这种情况的示例中:特征Respondernickel定义,Resultmongodb定义。

解决此问题的常用方法是通过将所需类型包装到具有单个组件的tuple struct(所谓的 newtype pattern )中来定义自己的类型:< / p>

struct Result(mongodb::error::Result<Option<Document>>);

impl Responder for Result {
    ...

答案 1 :(得分:1)

根据starblue的回答,我将ApiResponseApiError替换为元组结构,并按如下方式重构我的代码:

struct ApiResponse<T>(T);

impl<D> Responder<D> for ApiResponse<Result<Option<Document>>> {

    fn respond<'a>(self, mut response: Response<'a, D>) -> MiddlewareResult<'a, D> {

        let mut d = BTreeMap::new();
        match self.0 {
            Ok(Some(doc))=>{
                d.insert("data".to_string(),Bson::Document(doc).to_json());
            },
            Ok(None)=>{
                response.set(StatusCode::NotFound);
                d.insert("error".to_string(),"Not Found".to_json());
            },
            Err(e)=>{
                response.set(StatusCode::InternalServerError);
                d.insert("error".to_string(),format!("{}",e).to_json());
            }

        }
        response.set(MediaType::Json);
        response.send(Json::Object(d))
    }
}