ruma_common/identifiers/
mxc_uri.rs1use std::num::NonZeroU8;
6
7use ruma_identifiers_validation::{error::MxcUriError, mxc_uri::validate};
8use ruma_macros::IdDst;
9
10use super::ServerName;
11
12type Result<T, E = MxcUriError> = std::result::Result<T, E>;
13
14#[repr(transparent)]
18#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, IdDst)]
19#[ruma_id(smallvec_inline_bytes = 60)]
20pub struct MxcUri(str);
21
22impl MxcUri {
23 pub fn media_id(&self) -> Result<&str> {
25 self.parts().map(|(_, s)| s)
26 }
27
28 pub fn server_name(&self) -> Result<&ServerName> {
30 self.parts().map(|(s, _)| s)
31 }
32
33 pub fn parts(&self) -> Result<(&ServerName, &str)> {
36 self.extract_slash_idx().map(|idx| {
37 (
38 ServerName::from_borrowed_unchecked(&self.as_str()[6..idx.get() as usize]),
39 &self.as_str()[idx.get() as usize + 1..],
40 )
41 })
42 }
43
44 pub fn validate(&self) -> Result<()> {
46 self.extract_slash_idx().map(|_| ())
47 }
48
49 #[inline(always)]
51 pub fn is_valid(&self) -> bool {
52 self.validate().is_ok()
53 }
54
55 #[inline(always)]
57 fn extract_slash_idx(&self) -> Result<NonZeroU8> {
58 validate(self.as_str())
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use ruma_identifiers_validation::error::MxcUriError;
65
66 use super::{MxcUri, OwnedMxcUri};
67 use crate::server_name;
68
69 #[test]
70 fn parse_mxc_uri() {
71 let mxc = <&MxcUri>::from("mxc://127.0.0.1/asd32asdfasdsd");
72
73 assert!(mxc.is_valid());
74 assert_eq!(mxc.parts(), Ok((server_name!("127.0.0.1"), "asd32asdfasdsd")));
75 }
76
77 #[test]
78 fn parse_mxc_uri_without_media_id() {
79 let mxc = <&MxcUri>::from("mxc://127.0.0.1");
80
81 assert!(!mxc.is_valid());
82 assert_eq!(mxc.parts(), Err(MxcUriError::MissingSlash));
83 }
84
85 #[test]
86 fn parse_mxc_uri_without_protocol() {
87 assert!(!<&MxcUri>::from("127.0.0.1/asd32asdfasdsd").is_valid());
88 }
89
90 #[test]
91 fn serialize_mxc_uri() {
92 assert_eq!(
93 serde_json::to_string(<&MxcUri>::from("mxc://server/1234id"))
94 .expect("Failed to convert MxcUri to JSON."),
95 r#""mxc://server/1234id""#
96 );
97 }
98
99 #[test]
100 fn deserialize_mxc_uri() {
101 let mxc = serde_json::from_str::<OwnedMxcUri>(r#""mxc://server/1234id""#)
102 .expect("Failed to convert JSON to MxcUri");
103
104 assert_eq!(mxc, "mxc://server/1234id");
105 assert!(mxc.is_valid());
106 assert_eq!(mxc.parts(), Ok((server_name!("server"), "1234id")));
107 }
108}