ruma_common/identifiers/
direct_user_identifier.rs1use ruma_macros::IdDst;
2
3use super::{IdParseError, OwnedUserId, UserId};
4
5#[repr(transparent)]
11#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdDst)]
12#[ruma_id(smallvec_inline_bytes = 40)]
13pub struct DirectUserIdentifier(str);
14
15impl DirectUserIdentifier {
16 pub fn as_user_id(&self) -> Option<&UserId> {
18 self.as_str().try_into().ok()
19 }
20}
21
22impl OwnedDirectUserIdentifier {
23 pub fn as_user_id(&self) -> Option<&UserId> {
25 self.as_str().try_into().ok()
26 }
27
28 pub fn into_user_id(self) -> Option<OwnedUserId> {
30 self.try_into().ok()
31 }
32}
33
34impl TryFrom<OwnedDirectUserIdentifier> for OwnedUserId {
35 type Error = IdParseError;
36
37 fn try_from(value: OwnedDirectUserIdentifier) -> Result<Self, Self::Error> {
38 ruma_identifiers_validation::user_id::validate(value.as_str())?;
39 Ok(unsafe { Self::from_inner_unchecked(value.into_inner()) })
40 }
41}
42
43impl TryFrom<&OwnedDirectUserIdentifier> for OwnedUserId {
44 type Error = IdParseError;
45
46 fn try_from(value: &OwnedDirectUserIdentifier) -> Result<Self, Self::Error> {
47 ruma_identifiers_validation::user_id::validate(value.as_str())?;
48 Ok(unsafe { Self::from_inner_unchecked(value.clone().into_inner()) })
49 }
50}
51
52impl TryFrom<&DirectUserIdentifier> for OwnedUserId {
53 type Error = IdParseError;
54
55 fn try_from(value: &DirectUserIdentifier) -> Result<Self, Self::Error> {
56 value.as_str().try_into()
57 }
58}
59
60impl<'a> TryFrom<&'a DirectUserIdentifier> for &'a UserId {
61 type Error = IdParseError;
62
63 fn try_from(value: &'a DirectUserIdentifier) -> Result<Self, Self::Error> {
64 value.as_str().try_into()
65 }
66}
67
68impl From<OwnedUserId> for OwnedDirectUserIdentifier {
69 fn from(value: OwnedUserId) -> Self {
70 unsafe { Self::from_inner_unchecked(value.into_inner()) }
71 }
72}
73
74impl From<&OwnedUserId> for OwnedDirectUserIdentifier {
75 fn from(value: &OwnedUserId) -> Self {
76 unsafe { Self::from_inner_unchecked(value.clone().into_inner()) }
77 }
78}
79
80impl From<&UserId> for OwnedDirectUserIdentifier {
81 fn from(value: &UserId) -> Self {
82 Self::from_str_unchecked(value.as_str())
83 }
84}
85
86impl<'a> From<&'a UserId> for &'a DirectUserIdentifier {
87 fn from(value: &'a UserId) -> Self {
88 DirectUserIdentifier::from_borrowed_unchecked(value.as_str())
89 }
90}
91
92impl PartialEq<&UserId> for &DirectUserIdentifier {
93 fn eq(&self, other: &&UserId) -> bool {
94 self.as_str().eq(other.as_str())
95 }
96}
97
98impl PartialEq<&DirectUserIdentifier> for &UserId {
99 fn eq(&self, other: &&DirectUserIdentifier) -> bool {
100 other.as_str().eq(self.as_str())
101 }
102}
103
104impl PartialEq<OwnedUserId> for &DirectUserIdentifier {
105 fn eq(&self, other: &OwnedUserId) -> bool {
106 self.as_str().eq(other.as_str())
107 }
108}
109
110impl PartialEq<&DirectUserIdentifier> for OwnedUserId {
111 fn eq(&self, other: &&DirectUserIdentifier) -> bool {
112 other.as_str().eq(self.as_str())
113 }
114}
115
116impl PartialEq<&UserId> for OwnedDirectUserIdentifier {
117 fn eq(&self, other: &&UserId) -> bool {
118 self.as_str().eq(other.as_str())
119 }
120}
121
122impl PartialEq<OwnedDirectUserIdentifier> for &UserId {
123 fn eq(&self, other: &OwnedDirectUserIdentifier) -> bool {
124 other.as_str().eq(self.as_str())
125 }
126}
127
128impl PartialEq<OwnedUserId> for OwnedDirectUserIdentifier {
129 fn eq(&self, other: &OwnedUserId) -> bool {
130 self.as_str().eq(other.as_str())
131 }
132}
133
134impl PartialEq<OwnedDirectUserIdentifier> for OwnedUserId {
135 fn eq(&self, other: &OwnedDirectUserIdentifier) -> bool {
136 other.as_str().eq(self.as_str())
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use serde_json::{from_value as from_json_value, to_value as to_json_value};
143
144 use super::{DirectUserIdentifier, OwnedDirectUserIdentifier};
145 use crate::{OwnedUserId, user_id};
146
147 #[test]
148 fn user_id_conversion() {
149 let alice_direct_uid = <&DirectUserIdentifier>::from("@alice:ruma.io");
150 let alice_owned_user_id: OwnedUserId = alice_direct_uid
151 .to_owned()
152 .try_into()
153 .expect("@alice:ruma.io should be convertible into a Matrix user ID");
154 assert_eq!(alice_direct_uid, alice_owned_user_id);
155
156 let alice_direct_uid_mail = <&DirectUserIdentifier>::from("alice@ruma.io");
157 OwnedUserId::try_from(alice_direct_uid_mail.to_owned())
158 .expect_err("alice@ruma.io should not be convertible into a Matrix user ID");
159
160 let alice_user_id = user_id!("@alice:ruma.io");
161 let alice_direct_uid_mail: &DirectUserIdentifier = alice_user_id.into();
162 assert_eq!(alice_direct_uid_mail, alice_user_id);
163 assert_eq!(alice_direct_uid_mail, alice_user_id.to_owned());
164 assert_eq!(alice_user_id, alice_direct_uid_mail);
165 assert_eq!(alice_user_id.to_owned(), alice_direct_uid_mail);
166
167 let alice_user_id = user_id!("@alice:ruma.io");
168 let alice_direct_uid_mail: OwnedDirectUserIdentifier = alice_user_id.into();
169 assert_eq!(alice_direct_uid_mail, alice_user_id);
170 assert_eq!(alice_direct_uid_mail, alice_user_id.to_owned());
171 assert_eq!(alice_user_id, alice_direct_uid_mail);
172 assert_eq!(alice_user_id.to_owned(), alice_direct_uid_mail);
173
174 let alice_user_id = user_id!("@alice:ruma.io");
175 let alice_user_id_json = to_json_value(alice_user_id).unwrap();
176 let alice_direct_uid_mail: OwnedDirectUserIdentifier =
177 from_json_value(alice_user_id_json).unwrap();
178 assert_eq!(alice_user_id, alice_direct_uid_mail);
179 }
180}