ruma_common/profile/
profile_field_value_serde.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize, Serializer, de, ser::SerializeMap};
4
5use super::{CustomProfileFieldValue, ProfileFieldName, ProfileFieldValue};
6
7pub struct ProfileFieldValueVisitor(Option<ProfileFieldName>);
12
13impl ProfileFieldValueVisitor {
14 pub fn new(field: Option<ProfileFieldName>) -> Self {
16 Self(field)
17 }
18
19 fn find_field_name<'de, V>(self, map: &mut V) -> Result<Option<ProfileFieldName>, V::Error>
25 where
26 V: de::MapAccess<'de>,
27 {
28 while let Some(key) = map.next_key::<ProfileFieldName>()? {
29 if self.0.as_ref().is_none_or(|field| key == *field) {
30 return Ok(Some(key));
31 }
32 }
33
34 Ok(None)
35 }
36}
37
38impl<'de> de::Visitor<'de> for ProfileFieldValueVisitor {
39 type Value = Option<ProfileFieldValue>;
40
41 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
42 formatter.write_str("enum ProfileFieldValue")
43 }
44
45 fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
46 where
47 V: de::MapAccess<'de>,
48 {
49 let Some(field) = self.find_field_name(&mut map)? else {
50 return Ok(None);
51 };
52
53 Ok(Some(match field {
54 ProfileFieldName::AvatarUrl => ProfileFieldValue::AvatarUrl(map.next_value()?),
55 ProfileFieldName::DisplayName => ProfileFieldValue::DisplayName(map.next_value()?),
56 ProfileFieldName::TimeZone => ProfileFieldValue::TimeZone(map.next_value()?),
57 #[cfg(feature = "unstable-msc4426")]
58 ProfileFieldName::Status => ProfileFieldValue::Status(map.next_value()?),
59 #[cfg(feature = "unstable-msc4426")]
60 ProfileFieldName::Call => ProfileFieldValue::Call(map.next_value()?),
61 ProfileFieldName::_Custom(field) => {
62 ProfileFieldValue::_Custom(CustomProfileFieldValue {
63 field: field.0.into(),
64 value: map.next_value()?,
65 })
66 }
67 }))
68 }
69}
70
71impl<'de> Deserialize<'de> for ProfileFieldValue {
72 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
73 where
74 D: de::Deserializer<'de>,
75 {
76 deserializer
77 .deserialize_map(ProfileFieldValueVisitor(None))?
78 .ok_or_else(|| de::Error::invalid_length(0, &"at least one key-value pair"))
79 }
80}
81
82impl Serialize for CustomProfileFieldValue {
83 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84 where
85 S: Serializer,
86 {
87 let mut map = serializer.serialize_map(Some(1))?;
88 map.serialize_entry(&self.field, &self.value)?;
89 map.end()
90 }
91}