ruma_identifiers_validation/
mxc_uri.rs1use std::num::NonZeroU8;
2
3use crate::{error::MxcUriError, server_name};
4
5const PROTOCOL: &str = "mxc://";
6
7pub fn validate(uri: &str) -> Result<NonZeroU8, MxcUriError> {
8 let Some(uri) = uri.strip_prefix(PROTOCOL) else {
9 return Err(MxcUriError::WrongSchema);
10 };
11
12 let Some(index) = uri.find('/') else {
13 return Err(MxcUriError::MissingSlash);
14 };
15
16 let server_name = &uri[..index];
17 let media_id = &uri[index + 1..];
18 let media_id_is_valid = media_id
20 .bytes()
21 .all(|b| matches!(b, b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'-' | b'_' ));
22
23 if !media_id_is_valid {
24 Err(MxcUriError::MediaIdMalformed)
25 } else if server_name::validate(server_name).is_err() {
26 Err(MxcUriError::ServerNameMalformed)
27 } else {
28 Ok(NonZeroU8::new((index + 6) as u8).unwrap())
29 }
30}