From 8b0687b08c26072098b132b1e358f9ef1c68f8c0 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 3 Nov 2021 18:23:05 +0100 Subject: [PATCH] client-api: Add support for deserializing thirdparty_id_creds from an object --- crates/ruma-client-api/src/r0/uiaa.rs | 50 +++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/crates/ruma-client-api/src/r0/uiaa.rs b/crates/ruma-client-api/src/r0/uiaa.rs index 0a4b6ad4..6ae1eec7 100644 --- a/crates/ruma-client-api/src/r0/uiaa.rs +++ b/crates/ruma-client-api/src/r0/uiaa.rs @@ -524,7 +524,14 @@ impl IncomingOAuth2 { pub struct EmailIdentity<'a> { /// Thirdparty identifier credentials. #[cfg_attr(not(feature = "compat"), serde(rename = "threepidCreds"))] - #[cfg_attr(feature = "compat", serde(rename = "threepid_creds", alias = "threepidCreds"))] + #[cfg_attr( + feature = "compat", + serde( + rename = "threepid_creds", + alias = "threepidCreds", + deserialize_with = "deserialize_thirdparty_id_creds" + ) + )] pub thirdparty_id_creds: &'a [ThirdpartyIdCredentials], /// The value of the session key given by the homeserver, if any. @@ -552,7 +559,14 @@ impl IncomingEmailIdentity { pub struct Msisdn<'a> { /// Thirdparty identifier credentials. #[cfg_attr(not(feature = "compat"), serde(rename = "threepidCreds"))] - #[cfg_attr(feature = "compat", serde(rename = "threepid_creds", alias = "threepidCreds"))] + #[cfg_attr( + feature = "compat", + serde( + rename = "threepid_creds", + alias = "threepidCreds", + deserialize_with = "deserialize_thirdparty_id_creds" + ) + )] pub thirdparty_id_creds: &'a [ThirdpartyIdCredentials], /// The value of the session key given by the homeserver, if any. @@ -854,3 +868,35 @@ impl OutgoingResponse for UiaaResponse { } } } + +fn deserialize_thirdparty_id_creds<'de, D>(deserializer: D) -> Vec +where + D: Deserializer<'de>, +{ + use de::value::{MapAccessDeserializer, SeqAccessDeserializer}; + + struct CredsVisitor; + + impl<'de> de::Visitor<'de> for CredsVisitor { + type Value = Vec; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("an array or object") + } + + fn visit_seq(self, seq: A) -> Result + where + A: de::SeqAccess<'de>, + { + >::deserialize(SeqAccessDeserializer::new(seq)) + } + + fn visit_map(self, map: A) -> Result + where + A: de::MapAccess<'de>, + { + let creds = ThirdpartyIdCredentials::deserialize(MapAccessDeserializer::new(map))?; + Ok(vec![creds]) + } + } +}