Skip to main content

ruma_common/profile/
user_profile_update.rs

1//! An update to the profile information for a user.
2
3use std::collections::{BTreeMap, btree_map};
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value as JsonValue;
7
8use super::{ProfileFieldName, ProfileFieldValue, static_profile_field::StaticProfileField};
9
10/// An update to the profile information for a user.
11///
12/// This type is not supposed to be used directly, but merged into a
13/// [`UserProfile`](super::UserProfile).
14#[derive(Clone, Debug, Default, Serialize, Deserialize)]
15#[serde(transparent)]
16pub struct UserProfileUpdate(BTreeMap<String, JsonValue>);
17
18impl UserProfileUpdate {
19    /// Creates a new empty `UserProfileUpdate`.
20    pub fn new() -> Self {
21        Self::default()
22    }
23
24    /// Returns the value of the given profile field.
25    pub fn get(&self, field: &str) -> Option<&JsonValue> {
26        self.0.get(field)
27    }
28
29    /// Returns the value of the given [`StaticProfileField`].
30    ///
31    /// Returns `Ok(Some(_))` if the field is present and the value was deserialized
32    /// successfully, `Ok(None)` if the field is not set, or an error if deserialization of the
33    /// value failed.
34    pub fn get_static<F: StaticProfileField>(&self) -> Result<Option<F::Value>, serde_json::Error> {
35        self.0.get(F::NAME).map(|value| serde_json::from_value(value.clone())).transpose()
36    }
37
38    /// Gets an iterator over the fields of the profile.
39    pub fn iter(&self) -> btree_map::Iter<'_, String, JsonValue> {
40        self.0.iter()
41    }
42
43    /// Sets a field to the given value.
44    pub fn set(&mut self, field: String, value: JsonValue) {
45        self.0.insert(field, value);
46    }
47}
48
49impl FromIterator<(String, JsonValue)> for UserProfileUpdate {
50    fn from_iter<T: IntoIterator<Item = (String, JsonValue)>>(iter: T) -> Self {
51        Self(iter.into_iter().collect())
52    }
53}
54
55impl FromIterator<(ProfileFieldName, JsonValue)> for UserProfileUpdate {
56    fn from_iter<T: IntoIterator<Item = (ProfileFieldName, JsonValue)>>(iter: T) -> Self {
57        iter.into_iter().map(|(field, value)| (field.as_str().to_owned(), value)).collect()
58    }
59}
60
61impl FromIterator<ProfileFieldValue> for UserProfileUpdate {
62    fn from_iter<T: IntoIterator<Item = ProfileFieldValue>>(iter: T) -> Self {
63        iter.into_iter().map(|value| (value.field_name(), value.value().into_owned())).collect()
64    }
65}
66
67impl Extend<(String, JsonValue)> for UserProfileUpdate {
68    fn extend<T: IntoIterator<Item = (String, JsonValue)>>(&mut self, iter: T) {
69        self.0.extend(iter);
70    }
71}
72
73impl Extend<(ProfileFieldName, JsonValue)> for UserProfileUpdate {
74    fn extend<T: IntoIterator<Item = (ProfileFieldName, JsonValue)>>(&mut self, iter: T) {
75        self.extend(iter.into_iter().map(|(field, value)| (field.as_str().to_owned(), value)));
76    }
77}
78
79impl Extend<ProfileFieldValue> for UserProfileUpdate {
80    fn extend<T: IntoIterator<Item = ProfileFieldValue>>(&mut self, iter: T) {
81        self.extend(iter.into_iter().map(|value| (value.field_name(), value.value().into_owned())));
82    }
83}
84
85impl IntoIterator for UserProfileUpdate {
86    type Item = (String, JsonValue);
87    type IntoIter = btree_map::IntoIter<String, JsonValue>;
88
89    fn into_iter(self) -> Self::IntoIter {
90        self.0.into_iter()
91    }
92}