Skip to main content

matrix_sdk_test/
identifiers.rs

1//! Matrix identifiers.
2
3use std::{fmt, hash::Hash, sync::LazyLock};
4
5use indexmap::Equivalent;
6use ruma::{
7    OwnedUserId, UserId,
8    events::direct::{DirectUserIdentifier, OwnedDirectUserIdentifier},
9};
10use serde::Serialize;
11
12/// A Matrix user.
13///
14/// This can be converted to the following types with `.into()`:
15///
16/// - `&'static UserId`
17/// - `OwnedUserId`
18/// - `&'static DirectUserIdentifier`
19/// - `OwnedDirectUserIdentifier`
20///
21/// It implements `PartialEq` with all the ID types above, as well as with
22/// `serde_json::Value` to use with the `assert_eq!` macro.
23///
24/// It implements `Serialize` and `Into<String>` to use it with the `json!`
25/// macro.
26///
27/// It implements `Hash` and `Equivalent<OwnedUserId>` as well to be able to use
28/// it with methods like `IndexMap::get()` or `IndexMap::contains_key()`.
29///
30/// It can also be converted to a borrowed string with `.as_str()` to use it
31/// with methods like `HashMap::get()` or `HashSet::contains()`.
32#[derive(Debug, Clone, Copy)]
33pub enum User {
34    /// `@alice:server.name`
35    Alice,
36    /// `@bob:other.server`
37    Bob,
38    /// `@carol:other.server`
39    Carol,
40}
41
42/// Alice's user ID.
43static ALICE_USER_ID: LazyLock<OwnedUserId> = LazyLock::new(|| crate::ALICE.to_owned());
44/// Bob's user ID.
45static BOB_USER_ID: LazyLock<OwnedUserId> = LazyLock::new(|| crate::BOB.to_owned());
46/// Carol's user ID.
47static CAROL_USER_ID: LazyLock<OwnedUserId> = LazyLock::new(|| crate::CAROL.to_owned());
48
49impl User {
50    /// The user's ID.
51    ///
52    /// This unconventional return type allows to either clone the owned ID or
53    /// dereference it.
54    fn id(&self) -> &'static OwnedUserId {
55        match self {
56            User::Alice => &ALICE_USER_ID,
57            User::Bob => &BOB_USER_ID,
58            User::Carol => &CAROL_USER_ID,
59        }
60    }
61
62    /// The user's ID as a `&str`.
63    pub fn as_str(&self) -> &'static str {
64        self.id().as_str()
65    }
66}
67
68impl From<User> for OwnedUserId {
69    fn from(user: User) -> Self {
70        user.id().clone()
71    }
72}
73
74impl From<User> for &'static UserId {
75    fn from(user: User) -> Self {
76        user.id()
77    }
78}
79
80impl From<User> for OwnedDirectUserIdentifier {
81    fn from(user: User) -> Self {
82        user.id().clone().into()
83    }
84}
85
86impl From<User> for &'static DirectUserIdentifier {
87    fn from(user: User) -> Self {
88        <&UserId>::from(user).into()
89    }
90}
91
92impl From<User> for String {
93    fn from(user: User) -> Self {
94        user.id().as_str().to_owned()
95    }
96}
97
98impl PartialEq<OwnedUserId> for User {
99    fn eq(&self, other: &OwnedUserId) -> bool {
100        self.id().eq(other)
101    }
102}
103
104impl PartialEq<User> for OwnedUserId {
105    fn eq(&self, other: &User) -> bool {
106        self.eq(other.id())
107    }
108}
109
110impl PartialEq<&OwnedUserId> for User {
111    fn eq(&self, other: &&OwnedUserId) -> bool {
112        self.id().eq(*other)
113    }
114}
115
116impl PartialEq<User> for &OwnedUserId {
117    fn eq(&self, other: &User) -> bool {
118        (*self).eq(other.id())
119    }
120}
121
122impl PartialEq<&UserId> for User {
123    fn eq(&self, other: &&UserId) -> bool {
124        self.id().eq(other)
125    }
126}
127
128impl PartialEq<User> for &UserId {
129    fn eq(&self, other: &User) -> bool {
130        self.eq(other.id())
131    }
132}
133
134impl PartialEq<serde_json::Value> for User {
135    fn eq(&self, other: &serde_json::Value) -> bool {
136        self.id().as_str().eq(other)
137    }
138}
139
140impl PartialEq<User> for serde_json::Value {
141    fn eq(&self, other: &User) -> bool {
142        self.eq(other.id().as_str())
143    }
144}
145
146impl Equivalent<OwnedUserId> for User {
147    fn equivalent(&self, key: &OwnedUserId) -> bool {
148        key.eq(self.id())
149    }
150}
151
152impl Hash for User {
153    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
154        self.id().hash(state);
155    }
156}
157
158impl Serialize for User {
159    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
160    where
161        S: serde::Serializer,
162    {
163        self.id().serialize(serializer)
164    }
165}
166
167impl fmt::Display for User {
168    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169        self.id().fmt(f)
170    }
171}