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
68 #[test]
69 fn parse_mxc_uri() {
70 let mxc = <&MxcUri>::from("mxc://127.0.0.1/asd32asdfasdsd");
71
72 assert!(mxc.is_valid());
73 assert_eq!(
74 mxc.parts(),
75 Ok(("127.0.0.1".try_into().expect("Failed to create ServerName"), "asd32asdfasdsd"))
76 );
77 }
78
79 #[test]
80 fn parse_mxc_uri_without_media_id() {
81 let mxc = <&MxcUri>::from("mxc://127.0.0.1");
82
83 assert!(!mxc.is_valid());
84 assert_eq!(mxc.parts(), Err(MxcUriError::MissingSlash));
85 }
86
87 #[test]
88 fn parse_mxc_uri_without_protocol() {
89 assert!(!<&MxcUri>::from("127.0.0.1/asd32asdfasdsd").is_valid());
90 }
91
92 #[test]
93 fn serialize_mxc_uri() {
94 assert_eq!(
95 serde_json::to_string(<&MxcUri>::from("mxc://server/1234id"))
96 .expect("Failed to convert MxcUri to JSON."),
97 r#""mxc://server/1234id""#
98 );
99 }
100
101 #[test]
102 fn deserialize_mxc_uri() {
103 let mxc = serde_json::from_str::<OwnedMxcUri>(r#""mxc://server/1234id""#)
104 .expect("Failed to convert JSON to MxcUri");
105
106 assert_eq!(mxc.as_str(), "mxc://server/1234id");
107 assert!(mxc.is_valid());
108 assert_eq!(
109 mxc.parts(),
110 Ok(("server".try_into().expect("Failed to create ServerName"), "1234id"))
111 );
112 }
113}