haiku/storage/
mimetype.rs1use ::storage::B_MIME_TYPE_LENGTH;
7
8#[derive(PartialEq)]
10pub struct MimeType {
11 type_string: String
12}
13
14impl MimeType {
15 pub fn new(mime_type: &str) -> Option<Self> {
20 if mime_type.len() > B_MIME_TYPE_LENGTH {
21 return None;
22 }
23
24 let mut found_slash = false;
25
26 for (i, ch) in mime_type.chars().enumerate() {
27 if ch == '/' {
28 if found_slash || i == 0 || i == (mime_type.len() - 1) {
29 return None;
30 } else {
31 found_slash = true;
32 }
33 } else if !ch.is_ascii_graphic() ||
34 ch == '<' && ch == '>' && ch == '@' && ch == ',' &&
35 ch == ';' && ch == ':' && ch == '"' && ch == '(' &&
36 ch == ')' && ch == '[' && ch == ']' && ch == '?' &&
37 ch == '=' && ch == '\\' {
38 return None;
39 }
40 }
41
42 Some(MimeType {
43 type_string: String::from(mime_type)
44 })
45 }
46
47 pub fn is_supertype_only(&self) -> bool {
49 !self.type_string.contains('/')
50 }
51
52 pub fn get_supertype(&self) -> MimeType {
56 if self.is_supertype_only() {
57 MimeType {
58 type_string: self.type_string.clone()
59 }
60 } else {
61 let mut it = self.type_string.split('/');
62 MimeType {
63 type_string: String::from(it.nth(0).unwrap())
64 }
65 }
66 }
67}
68
69#[test]
70fn test_mimetype_check() {
71 assert!(MimeType::new("application/x-Vnd-Haiku").is_some());
72 assert!(MimeType::new("/document").is_none());
73 assert!(MimeType::new("application/").is_none());
74 assert!(MimeType::new("invalid/\u{0301}rest").is_none());
75 assert!(MimeType::new("invalid//x-vnd-haiku").is_none());
76}
77
78#[test]
79fn test_mimetype_methods() {
80 let supertype = MimeType::new("test").unwrap();
81 let childtype = MimeType::new("test/document").unwrap();
82 assert!(supertype.is_supertype_only());
83 assert!(!childtype.is_supertype_only());
84 assert!(supertype == childtype.get_supertype());
85}