summaryrefslogtreecommitdiffstats
path: root/third_party/rust/mime_guess/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/mime_guess/build.rs')
-rw-r--r--third_party/rust/mime_guess/build.rs191
1 files changed, 191 insertions, 0 deletions
diff --git a/third_party/rust/mime_guess/build.rs b/third_party/rust/mime_guess/build.rs
new file mode 100644
index 0000000000..ff4ea764ef
--- /dev/null
+++ b/third_party/rust/mime_guess/build.rs
@@ -0,0 +1,191 @@
+#[cfg(feature = "phf")]
+extern crate phf_codegen;
+extern crate unicase;
+
+use unicase::UniCase;
+
+use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io::BufWriter;
+use std::path::Path;
+
+use std::collections::BTreeMap;
+
+use mime_types::MIME_TYPES;
+
+#[path = "src/mime_types.rs"]
+mod mime_types;
+
+#[cfg(feature = "phf")]
+const PHF_PATH: &str = "::impl_::phf";
+
+fn main() {
+ let out_dir = env::var("OUT_DIR").unwrap();
+ let dest_path = Path::new(&out_dir).join("mime_types_generated.rs");
+ let mut outfile = BufWriter::new(File::create(dest_path).unwrap());
+
+ #[cfg(feature = "phf")]
+ build_forward_map(&mut outfile);
+
+ #[cfg(feature = "rev-mappings")]
+ build_rev_map(&mut outfile);
+}
+
+// Build forward mappings (ext -> mime type)
+#[cfg(feature = "phf")]
+fn build_forward_map<W: Write>(out: &mut W) {
+ use phf_codegen::Map as PhfMap;
+
+ let mut forward_map = PhfMap::new();
+ forward_map.phf_path(PHF_PATH);
+
+ let mut map_entries: Vec<(&str, Vec<&str>)> = Vec::new();
+
+ for &(key, types) in MIME_TYPES {
+ if let Some(&mut (key_, ref mut values)) = map_entries.last_mut() {
+ // deduplicate extensions
+ if key == key_ {
+ values.extend_from_slice(types);
+ continue;
+ }
+ }
+
+ map_entries.push((key, types.into()));
+ }
+
+ for (key, values) in map_entries {
+ forward_map.entry(
+ UniCase::new(key),
+ &format!("&{:?}", values),
+ );
+ }
+
+ writeln!(
+ out,
+ "static MIME_TYPES: phf::Map<UniCase<&'static str>, &'static [&'static str]> = \n{};",
+ forward_map.build()
+ )
+ .unwrap();
+}
+
+// Build reverse mappings (mime type -> ext)
+#[cfg(all(feature = "phf", feature = "rev-mappings"))]
+fn build_rev_map<W: Write>(out: &mut W) {
+ use phf_codegen::Map as PhfMap;
+
+ let dyn_map = get_rev_mappings();
+
+ let mut rev_map = PhfMap::new();
+ rev_map.phf_path(PHF_PATH);
+
+ let mut exts = Vec::new();
+
+ for (top, subs) in dyn_map {
+ let top_start = exts.len();
+
+ let mut sub_map = PhfMap::new();
+ sub_map.phf_path(PHF_PATH);
+
+ for (sub, sub_exts) in subs {
+ let sub_start = exts.len();
+ exts.extend(sub_exts);
+ let sub_end = exts.len();
+
+ sub_map.entry(sub, &format!("({}, {})", sub_start, sub_end));
+ }
+
+ let top_end = exts.len();
+
+ rev_map.entry(
+ top,
+ &format!(
+ "TopLevelExts {{ start: {}, end: {}, subs: {} }}",
+ top_start, top_end, sub_map.build()
+ ),
+ );
+ }
+
+ writeln!(
+ out,
+ "static REV_MAPPINGS: phf::Map<UniCase<&'static str>, TopLevelExts> = \n{};",
+ rev_map.build()
+ ).unwrap();
+
+ writeln!(out, "const EXTS: &'static [&'static str] = &{:?};", exts).unwrap();
+}
+
+#[cfg(all(not(feature = "phf"), feature = "rev-mappings"))]
+fn build_rev_map<W: Write>(out: &mut W) {
+ use std::fmt::Write as _;
+
+ macro_rules! unicase_const {
+ ($s:expr) => ({
+ format_args!("{}({:?})", (if $s.is_ascii() {
+ "UniCase::ascii"
+ } else {
+ "UniCase::unicode"
+ }), $s)
+ })
+ }
+
+ let dyn_map = get_rev_mappings();
+
+ write!(out, "static REV_MAPPINGS: &'static [(UniCase<&'static str>, TopLevelExts)] = &[").unwrap();
+
+ let mut exts = Vec::new();
+
+ for (top, subs) in dyn_map {
+ let top_start = exts.len();
+
+ let mut sub_map = String::new();
+
+ for (sub, sub_exts) in subs {
+ let sub_start = exts.len();
+ exts.extend(sub_exts);
+ let sub_end = exts.len();
+
+ write!(
+ sub_map,
+ "({}, ({}, {})),",
+ unicase_const!(sub), sub_start, sub_end
+ ).unwrap();
+ }
+
+ let top_end = exts.len();
+
+ write!(
+ out,
+ "({}, TopLevelExts {{ start: {}, end: {}, subs: &[{}] }}),",
+ unicase_const!(top), top_start, top_end, sub_map
+ ).unwrap();
+ }
+
+ writeln!(out, "];").unwrap();
+
+ writeln!(out, "const EXTS: &'static [&'static str] = &{:?};", exts).unwrap();
+}
+
+#[cfg(feature = "rev-mappings")]
+fn get_rev_mappings(
+) -> BTreeMap<UniCase<&'static str>, BTreeMap<UniCase<&'static str>, Vec<&'static str>>> {
+ // First, collect all the mime type -> ext mappings)
+ let mut dyn_map = BTreeMap::new();
+ for &(key, types) in MIME_TYPES {
+ for val in types {
+ let (top, sub) = split_mime(val);
+ dyn_map
+ .entry(UniCase::new(top))
+ .or_insert_with(BTreeMap::new)
+ .entry(UniCase::new(sub))
+ .or_insert_with(Vec::new)
+ .push(key);
+ }
+ }
+ dyn_map
+}
+
+fn split_mime(mime: &str) -> (&str, &str) {
+ let split_idx = mime.find('/').unwrap();
+ (&mime[..split_idx], &mime[split_idx + 1..])
+}