2015-12-24 86 views
0

我依靠rustc_serialize將JSON數據解析爲一個結構,Orders,它代表VecOrder結構。 JSON數據可能有一個數組或一個null值;我的意圖是要麼解析正常的訂單數組(如果有的話),要麼將null的值解析爲Orders,並且使用空的Vec。如果這兩種情況都不是這種情況,那麼就會傳遞一個錯誤。這是我的嘗試:在關聯類型的實例上模式匹配的難度

impl Decodable for Orders { 
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> { 
     let try = d.read_seq(|d, l| { 
      let mut orders = Vec::new(); 
      for _ in 0..l { 
       let order = try!(Decodable::decode(d)); 
       orders.push(order); 
      } 
      Ok(Orders(orders)) 
     }); 

     match try { 
      value @ Ok(_) => value, 
      error @ Err(e) => match e { 
       ExpectedError(_, x) if &x == "null" => Ok(Orders(Vec::new())), 
       _ => error, 
      }, 
     } 
    } 
} 

我的問題與ExpectedError上的模式匹配有關。編譯器給我以下錯誤:

expected `<D as rustc_serialize::serialize::Decoder>::Error`, 
    found `rustc_serialize::json::DecoderError` 
(expected associated type, 
    found enum `rustc_serialize::json::DecoderError`) [E0308] 
src/api/types/json.rs:125     ExpectedError(_, x) if &x == "null" => Ok(Orders(Vec::new())), 
              ^~~~~~~~~~~~~~~~~~~ 

我難住這一個。我該如何解決這個問題?

+0

你是否設法解決這個問題?如果是的話,我會高度讚賞一些更多的細節。謝謝 – maximi

回答

2

How can I correct this?

一般情況下,您將不得不在通用或專業之間進行選擇。您無法在關聯的類型上進行模式匹配,因爲此類型可以是任何類型,並且通用方法應該適用於滿足約束條件的任何類型。

例如,你的情況:

  • <D as rustc_serialize::serialize::Decoder>::Error可以什麼
  • rustc_serialize::json::DecoderError只是一種可能性

所以你通常應該使用一些抽象D或專業的選擇解碼爲json


但是,因爲你在這裏實現Decodable,你無法不選擇是通用的,你不來挑簽名。

而且,看來rustc_serialize不支持試探性解析(或至少,它json實現沒有),那麼恐怕你無法檢查無效(使用d.read_nil())提前。

我想這些限制可以被看作是該庫正在退休贊成serde,只能鼓勵你嘗試一下的原因。