Candid failed to decode for internal error

Here is my code:


#[derive(CandidType, Debug, Serialize, Deserialize)]
pub struct Suggection2 {
    pub id: i32,
    pub title: String,
    pub content: Option<String>,
    pub principal: String,
    pub created_at: time::OffsetDateTime,
}

#[test]
fn test_candid_decode() {
    let vecc: Vec<u8> = vec![
        68, 73, 68, 76, 3, 109, 1, 108, 5, 219, 183, 1, 117, 152, 171, 236, 129, 1, 113, 174, 157,
        177, 144, 1, 113, 185, 154, 222, 203, 1, 2, 170, 172, 217, 208, 6, 125, 110, 113, 1, 0, 1,
        1, 0, 0, 0, 7, 116, 105, 116, 108, 101, 95, 49, 63, 115, 54, 109, 53, 119, 45, 117, 51, 55,
        99, 107, 45, 119, 102, 121, 52, 102, 45, 120, 103, 108, 108, 116, 45, 106, 101, 114, 104,
        117, 45, 97, 120, 51, 51, 109, 45, 102, 114, 110, 53, 115, 45, 115, 97, 114, 105, 53, 45,
        115, 106, 99, 53, 100, 45, 55, 108, 55, 97, 110, 45, 120, 97, 101, 1, 9, 99, 111, 110, 116,
        101, 110, 116, 95, 50, 128, 160, 240, 150, 224, 181, 240, 2,
    ];
    let res: Result<(Vec<Suggection2>,), candid::Error> = candid::decode_args(&vecc);
    println!("test_candid_decode: {:?}", res);

    assert!(res.is_ok());
}
test_candid_decode: Err(Custom(Fail to decode argument 0 from table0 to vec record {
  id : int32;
  title : text;
  "principal" : text;
  content : opt text;
  created_at : nat;
}

Caused by:
    0: input: 4449444c036d016c05dbb7017598abec810171ae9db1900171b99adecb0102aaacd9d0067d6e7101000101000000077469746c655f313f73366d35772d753337636b2d77667934662d78676c6c742d6a657268752d617833336d2d66726e35732d73617269352d736a6335642d376c37616e2d7861650109636f6e74656e745f32_80a0f096e0b5f002
       table: type table0 = vec table1
       type table1 = record {
         23_515 : int32;
         272_307_608 : text;
         302_796_462 : text;
         427_265_337 : table2;
         1_779_848_746 : nat;
       }
       type table2 = opt text
       wire_type: nat, expect_type: nat
    1: Internal error at /root/.cargo/registry/src/index.crates.io-6f17d22bba15001f/candid-0.8.4/src/de.rs:548. Please file a bug.

The CandidType implmentation for time::OffsetDateTime strucu:

#[cfg(feature = "icp")]
impl CandidType for OffsetDateTime {
    fn _ty() -> Type {
        Type::Nat
    }

    fn idl_serialize<S>(&self, serializer: S) -> Result<(), S::Error>
    where
        S: Serializer,
    {
        let res = self.unix_timestamp_nanos();
        let res: u128 = res.abs().try_into().unwrap();
        let nat = candid::Nat::from(res);
        let res = serializer.serialize_nat(&nat);
        res
    }
}

#[cfg(feature = "icp")]
impl Default for OffsetDateTime {
    fn default() -> Self {
        let res = OffsetDateTime::from_unix_timestamp_nanos(ic_cdk::api::time().into()).unwrap();
        res
    }
}

Need help pls pls pls.

We need to implment our own Deserializer in this situation:

pub struct Suggection {
    pub id: i32,
    pub title: String,
    pub content: Option<String>,
    pub principal: String,
    #[serde(with = "timestamp_format")]
    pub created_at: time::OffsetDateTime,
}

mod timestamp_format {
    use candid::Deserialize;
    use serde::de::Error as SerdeError;
    use serde::{Deserializer, Serializer};
    use time::PrimitiveDateTime;
    use time::{Duration, OffsetDateTime};

    pub fn deserialize<'de, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
    where
        D: Deserializer<'de>,
    {
        let timestamp = u128::deserialize(deserializer)?;
        Ok(OffsetDateTime::from_unix_timestamp_nanos(timestamp.try_into().unwrap()).unwrap())
    }
}