#[ 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 ..])
}
Messung V0.5 in Prozent C=81 H=87 G=83
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-18)
¤
*© Formatika GbR, Deutschland