From 575e7e4c2fae39d867e6aee9af26ee7c3f857e0c Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Tue, 25 Jul 2023 12:44:30 -0700 Subject: [PATCH] recover subtype error from custom deserializer --- rust/candid/src/error.rs | 7 ++++++- rust/candid/tests/serde.rs | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/rust/candid/src/error.rs b/rust/candid/src/error.rs index c5a98134..9181d4a0 100644 --- a/rust/candid/src/error.rs +++ b/rust/candid/src/error.rs @@ -151,7 +151,12 @@ impl ser::Error for Error { impl de::Error for Error { fn custom(msg: T) -> Self { - Error::msg(format!("Deserialize error: {msg}")) + let msg = msg.to_string(); + if let Some(msg) = msg.strip_prefix("Subtyping error: ") { + Error::Subtype(msg.to_string()) + } else { + Error::msg(format!("Deserialize error: {msg}")) + } } fn invalid_type(_: de::Unexpected<'_>, exp: &dyn de::Expected) -> Self { Error::Subtype(format!("{exp}")) diff --git a/rust/candid/tests/serde.rs b/rust/candid/tests/serde.rs index c9f3186e..0bccb579 100644 --- a/rust/candid/tests/serde.rs +++ b/rust/candid/tests/serde.rs @@ -173,6 +173,20 @@ fn test_option() { // Deserialize \mu T.Option to a non-recursive type let v: Option>> = Some(Some(None)); test_decode(b"DIDL\x01\x6e\0\x01\0\x01\x01\0", &v); + // special opt rule + #[derive(CandidType, Deserialize, PartialEq, Debug)] + struct A { + canister_id: Option, + } + #[derive(CandidType, Deserialize, PartialEq, Debug)] + struct B { + canister_id: Option, + } + let bytes = encode(&B { + canister_id: Some(42), + }); + let expected = A { canister_id: None }; + test_decode(&bytes, &expected); } #[test]