Skip to content

Commit

Permalink
recover subtype error from custom deserializer
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyan-dfinity committed Jul 25, 2023
1 parent 581303e commit 575e7e4
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
7 changes: 6 additions & 1 deletion rust/candid/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,12 @@ impl ser::Error for Error {

impl de::Error for Error {
fn custom<T: std::fmt::Display>(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}"))
Expand Down
14 changes: 14 additions & 0 deletions rust/candid/tests/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,20 @@ fn test_option() {
// Deserialize \mu T.Option<T> to a non-recursive type
let v: Option<Option<Option<i32>>> = 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<candid::Principal>,
}
#[derive(CandidType, Deserialize, PartialEq, Debug)]
struct B {
canister_id: Option<i32>,
}
let bytes = encode(&B {
canister_id: Some(42),
});
let expected = A { canister_id: None };
test_decode(&bytes, &expected);
}

#[test]
Expand Down

0 comments on commit 575e7e4

Please sign in to comment.