ruma_common/profile/
user_profile_update.rs1use std::collections::BTreeMap;
4
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use serde_json::Value as JsonValue;
7
8use super::{ProfileFieldName, ProfileFieldValue, StaticProfileField};
9
10#[derive(Clone, Debug)]
12#[non_exhaustive]
13pub enum UserProfileUpdate {
14 Updated(UserProfileChanges),
16
17 Dropped,
19}
20
21impl<'d> Deserialize<'d> for UserProfileUpdate {
22 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
23 where
24 D: Deserializer<'d>,
25 {
26 Option::<UserProfileChanges>::deserialize(deserializer).map(|value| match value {
27 Some(changes) => Self::Updated(changes),
28 None => Self::Dropped,
29 })
30 }
31}
32
33impl Serialize for UserProfileUpdate {
34 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
35 where
36 S: Serializer,
37 {
38 match self {
39 Self::Updated(changes) => serializer.serialize_some(changes),
40 Self::Dropped => serializer.serialize_none(),
41 }
42 }
43}
44
45#[derive(Clone, Debug, Default, Serialize, Deserialize)]
51#[non_exhaustive]
52pub struct UserProfileChanges {
53 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
55 pub updated: BTreeMap<ProfileFieldName, JsonValue>,
56
57 #[serde(default, skip_serializing_if = "Vec::is_empty")]
59 pub removed: Vec<ProfileFieldName>,
60}
61
62impl UserProfileChanges {
63 pub fn new() -> Self {
65 Self::default()
66 }
67
68 pub fn get_updated_static<F: StaticProfileField>(
74 &self,
75 ) -> Result<Option<F::Value>, serde_json::Error> {
76 self.updated
77 .get(&ProfileFieldName::from(F::NAME))
78 .map(|value| serde_json::from_value(value.clone()))
79 .transpose()
80 }
81
82 pub fn insert_updated_value(&mut self, value: ProfileFieldValue) {
84 self.updated.insert(value.field_name(), value.value().into_owned());
85 }
86}