use std::process; use std::env; use std::fs::{read_dir, File}; use std::collections::HashMap; use namegen_compiler::manifest::Manifest; use std::env::join_paths; use std::path::Path; use namegen_compiler::input::SourceCollection; use glob::glob; use std::io::{Read}; use namegen::{Name, NamePart}; use namegen_compiler::output::{Output, Collection, CollectionItem}; const COMMON_FORMAT_NAMES: &'static [&str] = &[ "full_name", "full_name:female", "full_name:male", ]; fn main() { let source_dir = match env::var("SOURCE_DIR") { Ok(v) => v, Err(_) => { eprintln!("SOURCE_DIR missing"); process::exit(1); } }; let dest_dir = match env::var("DESTINATION_DIR") { Ok(v) => v, Err(_) => { eprintln!("DESTINATION_DIR missing"); process::exit(1); } }; let mut data = String::with_capacity(2048); let mut collection = Collection{items: Vec::new()}; for entry in read_dir(&source_dir).unwrap() { let entry = entry.unwrap(); if !entry.file_type().unwrap().is_file() { continue; } let path = Path::new(&source_dir).join(entry.file_name()); if path.to_str().unwrap().contains(".drone.yml") { continue; } eprintln!("Loading manifest {}", path.to_str().unwrap()); let manifest: Manifest = serde_yaml::from_reader(File::open(path.clone()).unwrap()).unwrap(); let mut coll = SourceCollection::default(); for source in manifest.sources.iter() { let path = path.with_file_name(&source.files); for entry in glob(path.to_str().unwrap()).expect("Failed to read glob pattern") { let path = entry.expect("Invalid file entry."); data.clear(); File::open(path.clone()).unwrap().read_to_string(&mut data); eprintln!("Loading source {} (size: {})", path.clone().to_str().unwrap(), data.len()); match source.kind.as_str() { "full_names" => { coll.load_full_names(&data, source).unwrap() } "labeled_groups" => { coll.load_labeled_groups(&data, source).unwrap() } _ => { eprintln!("Unknown source file kind {}", source.kind); process::exit(1); } } } } let mut name = Name::new(); for part in manifest.parts.iter() { eprintln!("Building part {}...", &part.name); let source = coll.source(&part.source).expect("Source not found."); let mut part = match part.kind.as_str() { "cfgrammar" => NamePart::new_cfgrammar( &part.name, &part.format_rules, &part.initial_tokens, part.rules.rlf, part.rules.ral, ), "markov" => NamePart::new_markov( &part.name, &part.format_rules, &part.initial_tokens, part.rules.lrs, part.rules.lrm, part.rules.lre, part.rules.rlf, ), "wordlist" => NamePart::new_wordlist( &part.name, &part.format_rules ), _ => { eprintln!("Unknown part kind {}", &part.kind); process::exit(1); }, }; for set in source.sets() { if set.labels().len() == 0 { eprintln!("\tSample list: {} samples", set.samples().len()); } else { eprintln!("\tSample group: {}", set.labels().join(" ")); } part.learn(set).unwrap() } name.add_part(part); } for format in manifest.formats.iter() { name.add_format(&format.name, &format.template) } let mut examples = HashMap::new(); for format in name.formats() { if let Some(gen) = name.generate(format.name()) { examples.insert(format.name().to_owned(), Vec::with_capacity(40)); for (i, result) in gen.enumerate().take(40) { examples.get_mut(format.name()).unwrap().push(result); } } } eprint!("\n"); eprintln!("Sample output"); for format_name in COMMON_FORMAT_NAMES.iter() { if let Some(gen) = name.generate(format_name) { eprint!("\n "); for (i, result) in gen.enumerate().take(72) { eprint!("{result: 0 && (i % 4 == 3) { eprint!("\n "); } } eprint!("\n"); } } if let Some(gen) = name.generate("long_full_name:male") { eprint!("\n "); for (i, result) in gen.enumerate().take(16) { eprint!("{result: 0 && (i % 2 == 1) { eprint!("\n "); } } eprint!("\n"); } let path = Path::new(&dest_dir).join(format!("{}.json", &manifest.name)); let mut output = Output{ name: manifest.name.clone(), metadata: manifest.metadata.clone(), data: name, examples: examples, }; eprintln!("Writing {}", path.clone().to_str().unwrap()); serde_json::to_writer(File::create(path).expect("Opening output filed failed"), &output).expect("Writing output failed."); collection.items.push(CollectionItem{name: output.name.clone(), metadata: output.metadata.clone()}); eprint!("\n\n"); } let path = Path::new(&dest_dir).join("_collection.json"); serde_json::to_writer(File::create(path).expect("Opening output filed failed"), &collection).expect("Writing collection failed."); }