1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
mod extensions; mod types; pub use extensions::EXTENSIONS; pub use types::TYPES; const DOT: &str = "."; pub fn lookup(ext: impl AsRef<str>) -> Option<&'static str> { let ext = &(DOT.to_owned() + &ext.as_ref().to_lowercase()) .rsplitn(2, DOT) .collect::<Vec<&str>>()[0] .to_owned(); if let Some((_, i)) = EXTENSIONS.iter().find(|(e, _)| *e == ext) { if let Some(kind) = TYPES.get(*i) { return Some(kind.0); } } None } pub fn extensions(t: impl AsRef<str>) -> Option<Vec<&'static str>> { let t = t.as_ref(); if let Some((_, s, e)) = TYPES.iter().find(|(e, _, _)| *e == t) { return Some((&EXTENSIONS[*s..(s + e)]).iter().map(|(e, _)| *e).collect()); } None } pub fn extension(t: impl AsRef<str>) -> Option<&'static str> { if let Some(exts) = extensions(t) { return Some(*exts.first().unwrap()); } None } #[cfg(test)] #[test] fn search() { assert_eq!(lookup("json").unwrap(), "application/json"); assert_eq!(lookup(".md").unwrap(), "text/markdown"); assert_eq!(lookup("folder/file.js").unwrap(), "application/javascript"); assert_eq!(lookup("folder/.htaccess"), None); assert_eq!(lookup("cats"), None); assert_eq!( extensions("application/octet-stream").unwrap(), vec![ "bin", "dms", "lrf", "mar", "so", "dist", "distz", "pkg", "bpk", "dump", "elc", "deploy", "exe", "dll", "deb", "dmg", "iso", "img", "msi", "msp", "msm", "buffer" ] ); assert_eq!(extension("application/octet-stream").unwrap(), "bin"); }