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 ProfileFieldName::_Custom(field) => {
58 ProfileFieldValue::_Custom(CustomProfileFieldValue {
59 field: field.0.into(),
60 value: map.next_value()?,
61 })
62 }
63 }))
64 }
65}
66
67impl<'de> Deserialize<'de> for ProfileFieldValue {
68 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
69 where
70 D: de::Deserializer<'de>,
71 {
72 deserializer
73 .deserialize_map(ProfileFieldValueVisitor(None))?
74 .ok_or_else(|| de::Error::invalid_length(0, &"at least one key-value pair"))
75 }
76}
77
78impl Serialize for CustomProfileFieldValue {
79 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
80 where
81 S: Serializer,
82 {
83 let mut map = serializer.serialize_map(Some(1))?;
84 map.serialize_entry(&self.field, &self.value)?;
85 map.end()
86 }
87}