@@ -71,6 +71,34 @@ impl TryFrom<&str> for UserID {
7171 }
7272}
7373
74+ impl TryFrom < String > for UserID {
75+ type Error = IdentifierError ;
76+
77+ /// Will try creating a `UserID` from the provided `&str`.
78+ /// Can fail if the user_id is incorrectly formatted.
79+ fn try_from ( s : String ) -> Result < Self , Self :: Error > {
80+ if !s. starts_with ( '@' ) {
81+ return Err ( IdentifierError :: IncorrectSigil ) ;
82+ }
83+
84+ if s. find ( ':' ) . is_none ( ) {
85+ return Err ( IdentifierError :: MissingColon ) ;
86+ }
87+
88+ Ok ( UserID ( s) )
89+ }
90+ }
91+
92+ impl < ' de > serde:: Deserialize < ' de > for UserID {
93+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
94+ where
95+ D : serde:: Deserializer < ' de > ,
96+ {
97+ let s: String = serde:: Deserialize :: deserialize ( deserializer) ?;
98+ UserID :: try_from ( s) . map_err ( serde:: de:: Error :: custom)
99+ }
100+ }
101+
74102impl Deref for UserID {
75103 type Target = str ;
76104
@@ -84,3 +112,141 @@ impl fmt::Display for UserID {
84112 write ! ( f, "{}" , self . 0 )
85113 }
86114}
115+
116+ /// A Matrix room_id.
117+ #[ derive( Clone , Debug , PartialEq ) ]
118+ pub struct RoomID ( String ) ;
119+
120+ impl RoomID {
121+ /// Returns the `localpart` of the room_id.
122+ pub fn localpart ( & self ) -> & str {
123+ & self [ 1 ..self . colon_pos ( ) ]
124+ }
125+
126+ /// Returns the `server_name` / `domain` of the room_id.
127+ pub fn server_name ( & self ) -> & str {
128+ & self [ self . colon_pos ( ) + 1 ..]
129+ }
130+
131+ /// Returns the position of the ':' inside of the room_id.
132+ /// Used when splitting the room_id into it's respective parts.
133+ fn colon_pos ( & self ) -> usize {
134+ self . find ( ':' ) . unwrap ( )
135+ }
136+ }
137+
138+ impl TryFrom < & str > for RoomID {
139+ type Error = IdentifierError ;
140+
141+ /// Will try creating a `RoomID` from the provided `&str`.
142+ /// Can fail if the room_id is incorrectly formatted.
143+ fn try_from ( s : & str ) -> Result < Self , Self :: Error > {
144+ if !s. starts_with ( '!' ) {
145+ return Err ( IdentifierError :: IncorrectSigil ) ;
146+ }
147+
148+ if s. find ( ':' ) . is_none ( ) {
149+ return Err ( IdentifierError :: MissingColon ) ;
150+ }
151+
152+ Ok ( RoomID ( s. to_string ( ) ) )
153+ }
154+ }
155+
156+ impl TryFrom < String > for RoomID {
157+ type Error = IdentifierError ;
158+
159+ /// Will try creating a `RoomID` from the provided `String`.
160+ /// Can fail if the room_id is incorrectly formatted.
161+ fn try_from ( s : String ) -> Result < Self , Self :: Error > {
162+ if !s. starts_with ( '!' ) {
163+ return Err ( IdentifierError :: IncorrectSigil ) ;
164+ }
165+
166+ if s. find ( ':' ) . is_none ( ) {
167+ return Err ( IdentifierError :: MissingColon ) ;
168+ }
169+
170+ Ok ( RoomID ( s) )
171+ }
172+ }
173+
174+ impl < ' de > serde:: Deserialize < ' de > for RoomID {
175+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
176+ where
177+ D : serde:: Deserializer < ' de > ,
178+ {
179+ let s: String = serde:: Deserialize :: deserialize ( deserializer) ?;
180+ RoomID :: try_from ( s) . map_err ( serde:: de:: Error :: custom)
181+ }
182+ }
183+
184+ impl Deref for RoomID {
185+ type Target = str ;
186+
187+ fn deref ( & self ) -> & Self :: Target {
188+ & self . 0
189+ }
190+ }
191+
192+ impl fmt:: Display for RoomID {
193+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
194+ write ! ( f, "{}" , self . 0 )
195+ }
196+ }
197+
198+ /// A Matrix event_id.
199+ #[ derive( Clone , Debug , PartialEq ) ]
200+ pub struct EventID ( String ) ;
201+
202+ impl TryFrom < & str > for EventID {
203+ type Error = IdentifierError ;
204+
205+ /// Will try creating a `EventID` from the provided `&str`.
206+ /// Can fail if the event_id is incorrectly formatted.
207+ fn try_from ( s : & str ) -> Result < Self , Self :: Error > {
208+ if !s. starts_with ( '$' ) {
209+ return Err ( IdentifierError :: IncorrectSigil ) ;
210+ }
211+
212+ Ok ( EventID ( s. to_string ( ) ) )
213+ }
214+ }
215+
216+ impl TryFrom < String > for EventID {
217+ type Error = IdentifierError ;
218+
219+ /// Will try creating a `EventID` from the provided `String`.
220+ /// Can fail if the event_id is incorrectly formatted.
221+ fn try_from ( s : String ) -> Result < Self , Self :: Error > {
222+ if !s. starts_with ( '$' ) {
223+ return Err ( IdentifierError :: IncorrectSigil ) ;
224+ }
225+
226+ Ok ( EventID ( s) )
227+ }
228+ }
229+
230+ impl < ' de > serde:: Deserialize < ' de > for EventID {
231+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
232+ where
233+ D : serde:: Deserializer < ' de > ,
234+ {
235+ let s: String = serde:: Deserialize :: deserialize ( deserializer) ?;
236+ EventID :: try_from ( s) . map_err ( serde:: de:: Error :: custom)
237+ }
238+ }
239+
240+ impl Deref for EventID {
241+ type Target = str ;
242+
243+ fn deref ( & self ) -> & Self :: Target {
244+ & self . 0
245+ }
246+ }
247+
248+ impl fmt:: Display for EventID {
249+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
250+ write ! ( f, "{}" , self . 0 )
251+ }
252+ }
0 commit comments