Skip to main content

ruma_common/profile/
user_profile.rs

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