Skip to content

Commit

Permalink
Format code using 'cargo fmt' (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
Atul9 authored and abonander committed Apr 25, 2019
1 parent d3e0d79 commit 5b79519
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 59 deletions.
29 changes: 20 additions & 9 deletions build.rs
Expand Up @@ -5,17 +5,17 @@ use phf_codegen::Map as PhfMap;

use unicase::UniCase;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufWriter;
use std::path::Path;
use std::env;

use std::collections::BTreeMap;

use mime_types::MIME_TYPES;

#[path="src/mime_types.rs"]
#[path = "src/mime_types.rs"]
mod mime_types;

fn main() {
Expand All @@ -30,7 +30,11 @@ fn main() {

// Build forward mappings (ext -> mime type)
fn build_forward_map<W: Write>(out: &mut W) {
write!(out, "static MIME_TYPES: phf::Map<UniCase<&'static str>, &'static str> = ").unwrap();
write!(
out,
"static MIME_TYPES: phf::Map<UniCase<&'static str>, &'static str> = "
)
.unwrap();
let mut forward_map = PhfMap::new();

for &(key, val) in MIME_TYPES {
Expand All @@ -42,22 +46,26 @@ fn build_forward_map<W: Write>(out: &mut W) {
writeln!(out, ";").unwrap();
}


// Build reverse mappings (mime type -> ext)
fn build_rev_map<W: Write>(out: &mut W) {
// First, collect all the mime type -> ext mappings)
let mut dyn_map = BTreeMap::new();

for &(key, val) in MIME_TYPES {
let (top, sub) = split_mime(val);
dyn_map.entry(UniCase(top))
dyn_map
.entry(UniCase(top))
.or_insert_with(BTreeMap::new)
.entry(UniCase(sub))
.or_insert_with(Vec::new)
.push(key);
}

write!(out, "static REV_MAPPINGS: phf::Map<UniCase<&'static str>, TopLevelExts> = ").unwrap();
write!(
out,
"static REV_MAPPINGS: phf::Map<UniCase<&'static str>, TopLevelExts> = "
)
.unwrap();

let mut rev_map = PhfMap::new();

Expand All @@ -68,7 +76,7 @@ fn build_rev_map<W: Write>(out: &mut W) {

let mut sub_map = PhfMap::new();

for(sub, sub_exts) in subs {
for (sub, sub_exts) in subs {
let sub_start = exts.len();
exts.extend(sub_exts);
let sub_end = exts.len();
Expand All @@ -85,7 +93,10 @@ fn build_rev_map<W: Write>(out: &mut W) {

rev_map.entry(
top,
&format!("TopLevelExts {{ start: {}, end: {}, subs: {} }}", top_start, top_end, subs_str)
&format!(
"TopLevelExts {{ start: {}, end: {}, subs: {} }}",
top_start, top_end, subs_str
),
);
}

Expand All @@ -97,5 +108,5 @@ fn build_rev_map<W: Write>(out: &mut W) {

fn split_mime(mime: &str) -> (&str, &str) {
let split_idx = mime.find('/').unwrap();
(&mime[..split_idx], &mime[split_idx + 1 ..])
(&mime[..split_idx], &mime[split_idx + 1..])
}
6 changes: 5 additions & 1 deletion examples/rev_map.rs
Expand Up @@ -6,5 +6,9 @@ fn main() {
}

fn print_exts(mime_type: &str) {
println!("Exts for {:?}: {:?}", mime_type, mime_guess::get_mime_extensions_str(mime_type));
println!(
"Exts for {:?}: {:?}",
mime_type,
mime_guess::get_mime_extensions_str(mime_type)
);
}
79 changes: 54 additions & 25 deletions src/lib.rs
Expand Up @@ -59,8 +59,7 @@ mod mime_types_src;
///
/// [rfc7231]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5
pub fn guess_mime_type<P: AsRef<Path>>(path: P) -> Mime {
guess_mime_type_opt(path)
.unwrap_or_else(octet_stream)
guess_mime_type_opt(path).unwrap_or_else(octet_stream)
}

/// Guess the MIME type of `path` by its extension (as defined by `Path::extension()`).
Expand All @@ -74,8 +73,7 @@ pub fn guess_mime_type<P: AsRef<Path>>(path: P) -> Mime {
///
/// Take care when processing files with assumptions based on the return value of this function.
pub fn guess_mime_type_opt<P: AsRef<Path>>(path: P) -> Option<Mime> {
mime_str_for_path_ext(path)
.map(|mime| mime.parse::<Mime>().unwrap())
mime_str_for_path_ext(path).map(|mime| mime.parse::<Mime>().unwrap())
}

/// Guess the MIME type string of `path` by its extension (as defined by `Path::extension()`).
Expand All @@ -89,7 +87,11 @@ pub fn guess_mime_type_opt<P: AsRef<Path>>(path: P) -> Option<Mime> {
///
/// Take care when processing files with assumptions based on the return value of this function.
pub fn mime_str_for_path_ext<P: AsRef<Path>>(path: P) -> Option<&'static str> {
let ext = path.as_ref().extension().and_then(OsStr::to_str).unwrap_or("");
let ext = path
.as_ref()
.extension()
.and_then(OsStr::to_str)
.unwrap_or("");

get_mime_type_str(ext)
}
Expand All @@ -105,17 +107,15 @@ pub fn mime_str_for_path_ext<P: AsRef<Path>>(path: P) -> Option<&'static str> {
///
/// [rfc7231]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5
pub fn get_mime_type(search_ext: &str) -> Mime {
get_mime_type_opt(search_ext)
.unwrap_or_else(octet_stream)
get_mime_type_opt(search_ext).unwrap_or_else(octet_stream)
}

/// Get the MIME type associated with a file extension.
///
/// If there is no association for the extension, or `ext` is empty,
/// `None` is returned.
pub fn get_mime_type_opt(search_ext: &str) -> Option<Mime> {
get_mime_type_str(search_ext)
.map(|mime| mime.parse::<Mime>().unwrap())
get_mime_type_str(search_ext).map(|mime| mime.parse::<Mime>().unwrap())
}

/// Get the MIME type string associated with a file extension. Case-insensitive.
Expand All @@ -125,7 +125,9 @@ pub fn get_mime_type_opt(search_ext: &str) -> Option<Mime> {
///
/// Returns `None` if `search_ext` is empty or an associated extension was not found.
pub fn get_mime_type_str(search_ext: &str) -> Option<&'static str> {
if search_ext.is_empty() { return None; }
if search_ext.is_empty() {
return None;
}

map_lookup(&MIME_TYPES, search_ext).cloned()
}
Expand Down Expand Up @@ -166,7 +168,7 @@ pub fn get_mime_extensions_str(mut mime_str: &str) -> Option<&'static [&'static

let (top, sub) = {
let split_idx = mime_str.find('/').unwrap();
(&mime_str[..split_idx], &mime_str[split_idx + 1 ..])
(&mime_str[..split_idx], &mime_str[split_idx + 1..])
};

get_extensions(top, sub)
Expand All @@ -189,19 +191,22 @@ pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'stat
let top = try_opt!(map_lookup(&REV_MAPPINGS, toplevel));

if sublevel == "*" {
return Some(&EXTS[top.start .. top.end]);
return Some(&EXTS[top.start..top.end]);
}

let sub = try_opt!(map_lookup(&top.subs, sublevel));
Some(&EXTS[sub.0 .. sub.1])
Some(&EXTS[sub.0..sub.1])
}

/// Get the MIME type for `application/octet-stream` (generic binary stream)
pub fn octet_stream() -> Mime {
"application/octet-stream".parse().unwrap()
}

fn map_lookup<'map, V>(map: &'map phf::Map<UniCase<&'static str>, V>, key: &str) -> Option<&'map V> {
fn map_lookup<'map, V>(
map: &'map phf::Map<UniCase<&'static str>, V>,
key: &str,
) -> Option<&'map V> {
// This transmute should be safe as `get` will not store the reference with
// the expanded lifetime. This is due to `Borrow` being overly strict and
// can't have an impl for `&'static str` to `Borrow<&'a str>`.
Expand All @@ -213,29 +218,49 @@ fn map_lookup<'map, V>(map: &'map phf::Map<UniCase<&'static str>, V>, key: &str)

#[cfg(test)]
mod tests {
use super::{get_mime_type, guess_mime_type, MIME_TYPES};
use super::{get_mime_type_opt, guess_mime_type_opt};
use mime::Mime;
use std::ascii::AsciiExt;
use std::path::Path;
use super::{get_mime_type, guess_mime_type, MIME_TYPES};
use super::{get_mime_type_opt, guess_mime_type_opt};

#[test]
fn test_mime_type_guessing() {
assert_eq!(get_mime_type("gif").to_string(), "image/gif".to_string());
assert_eq!(get_mime_type("TXT").to_string(), "text/plain".to_string());
assert_eq!(get_mime_type("blahblah").to_string(), "application/octet-stream".to_string());

assert_eq!(guess_mime_type(Path::new("/path/to/file.gif")).to_string(), "image/gif".to_string());
assert_eq!(guess_mime_type("/path/to/file.gif").to_string(), "image/gif".to_string());
assert_eq!(
get_mime_type("blahblah").to_string(),
"application/octet-stream".to_string()
);

assert_eq!(
guess_mime_type(Path::new("/path/to/file.gif")).to_string(),
"image/gif".to_string()
);
assert_eq!(
guess_mime_type("/path/to/file.gif").to_string(),
"image/gif".to_string()
);
}

#[test]
fn test_mime_type_guessing_opt() {
assert_eq!(get_mime_type_opt("gif").unwrap().to_string(), "image/gif".to_string());
assert_eq!(get_mime_type_opt("TXT").unwrap().to_string(), "text/plain".to_string());
assert_eq!(
get_mime_type_opt("gif").unwrap().to_string(),
"image/gif".to_string()
);
assert_eq!(
get_mime_type_opt("TXT").unwrap().to_string(),
"text/plain".to_string()
);
assert_eq!(get_mime_type_opt("blahblah"), None);

assert_eq!(guess_mime_type_opt("/path/to/file.gif").unwrap().to_string(), "image/gif".to_string());
assert_eq!(
guess_mime_type_opt("/path/to/file.gif")
.unwrap()
.to_string(),
"image/gif".to_string()
);
assert_eq!(guess_mime_type_opt("/path/to/file"), None);
}

Expand Down Expand Up @@ -263,7 +288,8 @@ mod tests {
ext <= n_ext,
"Extensions in src/mime_types should be sorted alphabetically
in ascending order. Failed assert: {:?} <= {:?}",
ext, n_ext
ext,
n_ext
);
}
}
Expand All @@ -290,7 +316,10 @@ mod bench {

#[bench]
fn bench_mime_str_uppercase(b: &mut Bencher) {
let uppercased : Vec<_> = MIME_TYPES.into_iter().map(|(s, _)| s.to_uppercase()).collect();
let uppercased: Vec<_> = MIME_TYPES
.into_iter()
.map(|(s, _)| s.to_uppercase())
.collect();

for mime_ext in &uppercased {
b.iter(|| {
Expand Down

0 comments on commit 5b79519

Please sign in to comment.