use std::collections::hash_set::HashSet; use std::env; use std::fs::File; use std::io::{BufRead, BufReader, BufWriter, Write}; use std::path::Path; type Result = ::std::result::Result; fn main() -> Result<()> { let names = load("names.txt")?; generate("codegen_names.rs", "NAMES", "PdfName", names)?; let keywords = load("keywords.txt")?; generate("codegen_keywords.rs", "KEYWORDS", "PdfKeyword", keywords)?; Ok(()) } fn safe(s: String) -> String { let mut d = "".to_owned(); for ch in s.chars() { match ch { '*' => d.push_str("star"), '\'' => d.push_str("apos"), '"' => d.push_str("quote"), ch @ _ => d.push(ch), } } d } fn load(filename: &str) -> Result> { let mut strings = HashSet::::new(); strings.insert("Unknown".to_owned()); let of = File::open(filename)?; let file = BufReader::new(&of); for (_, line) in file.lines().enumerate() { let l = line.unwrap().trim().to_owned(); if l.len() > 0 && l.chars().next().unwrap() != '#' { strings.insert(l.to_owned()); } } Ok(strings.into_iter().collect()) } fn generate(filename: &str, target: &str, typename: &str, entries: Vec) -> Result<()> { let path = Path::new(&env::var("OUT_DIR").unwrap()).join(filename); let mut file = BufWriter::new(File::create(&path).unwrap()); writeln!(&mut file, "#[derive(Debug, Clone, PartialEq, Eq, Hash)]")?; writeln!(&mut file, "#[allow(non_camel_case_types)]")?; writeln!(&mut file, "pub enum {} {{", typename)?; for entry in entries.iter() { writeln!(&mut file, " r#{},", safe(entry.to_owned()))?; } writeln!(&mut file, "}}\n")?; write!( &mut file, "pub static {}: phf::Map<&'static str, {}> = ", target, typename )?; let mut builder = phf_codegen::Map::new(); for entry in entries.iter() { builder.entry( &entry[..], &format!("{}::r#{}", typename, safe(entry.to_owned())), ); } writeln!(&mut file, "{};", builder.build())?; Ok(()) }