2016-02-12 65 views
3

我正在使用Nickel.rs與MongoDB構建RESTful api。 我想爲類型mongodb::error::Result<Option<bson::Document>>實施通用Responder錯誤:類型參數`D`必須用作某些本地類型的類型參數

這是我根據我發現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() 
      } 

     } 
    } 
} 

,我發現了以下錯誤:

error: type parameter D must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]

我跑rustc --explain E0210一個解釋,如果我的理解是正確的,我需要爲impl<D>提供一個特徵D作爲類型參數,但我不明白提供哪種特徵。

我試過impl<D: =()>但這樣做產生了同樣的錯誤。

+1

哪裏了'Responder'特質從何而來? –

+2

「或者您正在實施它的特性或類型必須在與impl相同的包中定義」https://doc.rust-lang.org/book/traits.html#rules-爲實現特質 – starblue

+0

響應者特質來自鎳:http://docs.nickel.rs/nickel/trait.Responder.html – menawi

回答

4

當你實現一個特質,然後either the trait or the type you are implementing it for must be defined in the same crate。在你的例子中情況並非如此:特徵Respondernickel定義,並且Resultmongodb定義。

合作解決這個問題的常用方法是定義你自己的類型,用單組分包裝所需的類型爲tuple struct(所謂NEWTYPE模式):基於

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

impl Responder for Result { 
    ... 
+0

閱讀您的評論後,我明白瞭解釋的意思,並且我完全按照您在答案中所描述的內容進行了操作。非常感謝! – menawi

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)) 
    } 
} 
相關問題