From 9cfa3b075cdc7fc1bebe26a88db8bfb662f61a11 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 10 Mar 2021 22:06:22 +0900 Subject: [PATCH] deserialize empty string to none for `avatar_url` --- ruma-client-api/src/r0/directory.rs | 4 + .../src/r0/membership/joined_members.rs | 4 + .../src/r0/profile/get_avatar_url.rs | 4 + ruma-client-api/src/r0/profile/get_profile.rs | 4 + .../src/r0/search/search_events.rs | 4 + .../src/r0/user_directory/search_users.rs | 4 + ruma-common/src/directory.rs | 4 + ruma-events/src/presence.rs | 32 ++++++++ ruma-events/src/room/member.rs | 79 +++++++++++++++++++ .../src/query/get_profile_information/v1.rs | 4 + 10 files changed, 143 insertions(+) diff --git a/ruma-client-api/src/r0/directory.rs b/ruma-client-api/src/r0/directory.rs index 3216454a..1c61be48 100644 --- a/ruma-client-api/src/r0/directory.rs +++ b/ruma-client-api/src/r0/directory.rs @@ -45,6 +45,10 @@ pub struct PublicRoomsChunk { /// The URL for the room's avatar, if one is set. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, } diff --git a/ruma-client-api/src/r0/membership/joined_members.rs b/ruma-client-api/src/r0/membership/joined_members.rs index 128b1f7a..1999b37c 100644 --- a/ruma-client-api/src/r0/membership/joined_members.rs +++ b/ruma-client-api/src/r0/membership/joined_members.rs @@ -55,6 +55,10 @@ pub struct RoomMember { /// The mxc avatar url of the user. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, } diff --git a/ruma-client-api/src/r0/profile/get_avatar_url.rs b/ruma-client-api/src/r0/profile/get_avatar_url.rs index 0abe2c9f..2a2cd6b2 100644 --- a/ruma-client-api/src/r0/profile/get_avatar_url.rs +++ b/ruma-client-api/src/r0/profile/get_avatar_url.rs @@ -26,6 +26,10 @@ ruma_api! { response: { /// The user's avatar URL, if set. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option } diff --git a/ruma-client-api/src/r0/profile/get_profile.rs b/ruma-client-api/src/r0/profile/get_profile.rs index ad6ea6bd..502e8080 100644 --- a/ruma-client-api/src/r0/profile/get_profile.rs +++ b/ruma-client-api/src/r0/profile/get_profile.rs @@ -26,6 +26,10 @@ ruma_api! { response: { /// The user's avatar URL, if set. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, /// The user's display name, if set. diff --git a/ruma-client-api/src/r0/search/search_events.rs b/ruma-client-api/src/r0/search/search_events.rs index 593dbb7b..c7478e6a 100644 --- a/ruma-client-api/src/r0/search/search_events.rs +++ b/ruma-client-api/src/r0/search/search_events.rs @@ -437,6 +437,10 @@ impl SearchResult { pub struct UserProfile { /// The user's avatar URL, if set. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, /// The user's display name, if set. diff --git a/ruma-client-api/src/r0/user_directory/search_users.rs b/ruma-client-api/src/r0/user_directory/search_users.rs index c896712f..43fbc98a 100644 --- a/ruma-client-api/src/r0/user_directory/search_users.rs +++ b/ruma-client-api/src/r0/user_directory/search_users.rs @@ -79,5 +79,9 @@ pub struct User { /// The avatar url, as an MXC, if one exists. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, } diff --git a/ruma-common/src/directory.rs b/ruma-common/src/directory.rs index a3766e0a..1bb904db 100644 --- a/ruma-common/src/directory.rs +++ b/ruma-common/src/directory.rs @@ -51,6 +51,10 @@ pub struct PublicRoomsChunk { /// The URL for the room's avatar, if one is set. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, } diff --git a/ruma-events/src/presence.rs b/ruma-events/src/presence.rs index 1264675f..cfe771c4 100644 --- a/ruma-events/src/presence.rs +++ b/ruma-events/src/presence.rs @@ -27,6 +27,10 @@ pub struct PresenceEvent { pub struct PresenceEventContent { /// The current avatar URL for this user. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, /// Whether or not the user is currently active. @@ -119,5 +123,33 @@ mod tests { && sender == "@example:localhost" && last_active_ago == uint!(2_478_593) ); + + #[cfg(feature = "compat")] + assert_matches!( + from_json_value::(json!({ + "content": { + "avatar_url": "", + "currently_active": false, + "last_active_ago": 2_478_593, + "presence": "online", + "status_msg": "Making cupcakes" + }, + "sender": "@example:localhost", + "type": "m.presence" + })).unwrap(), + PresenceEvent { + content: PresenceEventContent { + avatar_url: None, + currently_active: Some(false), + displayname: None, + last_active_ago: Some(last_active_ago), + presence: PresenceState::Online, + status_msg: Some(status_msg), + }, + sender, + } if status_msg == "Making cupcakes" + && sender == "@example:localhost" + && last_active_ago == uint!(2_478_593) + ); } } diff --git a/ruma-events/src/room/member.rs b/ruma-events/src/room/member.rs index b5d038cc..ad3f1d8f 100644 --- a/ruma-events/src/room/member.rs +++ b/ruma-events/src/room/member.rs @@ -42,6 +42,10 @@ pub type MemberEvent = StateEvent; pub struct MemberEventContent { /// The avatar URL for this user, if any. This is added by the homeserver. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, /// The display name for this user, if any. This is added by the homeserver. @@ -502,5 +506,80 @@ mod tests { } && token == "abc123" ); + + #[cfg(feature = "compat")] + assert_matches!( + from_json_value::>>(json!({ + "type": "m.room.member", + "content": { + "membership": "join" + }, + "event_id": "$143273582443PhrSn:example.org", + "origin_server_ts": 233, + "prev_content": { + "avatar_url": "", + "displayname": "Alice Margatroid", + "is_direct": true, + "membership": "invite", + "third_party_invite": { + "display_name": "alice", + "signed": { + "mxid": "@alice:example.org", + "signatures": { + "magic.forest": { + "ed25519:3": "foobar" + } + }, + "token": "abc123" + } + } + }, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@alice:example.org", + "state_key": "@alice:example.org" + })) + .unwrap() + .deserialize() + .unwrap(), + StateEvent:: { + content: MemberEventContent { + avatar_url: None, + displayname: None, + is_direct: None, + membership: MembershipState::Join, + third_party_invite: None, + }, + event_id, + origin_server_ts, + room_id, + sender, + state_key, + unsigned, + prev_content: Some(MemberEventContent { + avatar_url: None, + displayname: Some(displayname), + is_direct: Some(true), + membership: MembershipState::Invite, + third_party_invite: Some(ThirdPartyInvite { + display_name: third_party_displayname, + signed: SignedContent { mxid, signatures, token }, + }), + }), + } if event_id == "$143273582443PhrSn:example.org" + && origin_server_ts == UNIX_EPOCH + Duration::from_millis(233) + && room_id == "!jEsUZKDJdhlrceRyVU:example.org" + && sender == "@alice:example.org" + && state_key == "@alice:example.org" + && unsigned.is_empty() + && displayname == "Alice Margatroid" + && third_party_displayname == "alice" + && mxid == "@alice:example.org" + && signatures == btreemap! { + server_name!("magic.forest") => btreemap! { + server_signing_key_id!("ed25519:3") => "foobar".to_owned() + } + } + && token == "abc123" + ); } } diff --git a/ruma-federation-api/src/query/get_profile_information/v1.rs b/ruma-federation-api/src/query/get_profile_information/v1.rs index 265d784c..53bf7047 100644 --- a/ruma-federation-api/src/query/get_profile_information/v1.rs +++ b/ruma-federation-api/src/query/get_profile_information/v1.rs @@ -33,6 +33,10 @@ ruma_api! { /// Avatar URL for the user's avatar. #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "compat", + serde(default, deserialize_with = "ruma_serde::empty_string_as_none") + )] pub avatar_url: Option, } }