Viewing:
extern crate scripture_types;
extern crate phf_codegen;
extern crate phf;
use std::fs::File;
use std::io::{BufReader, BufWriter, Read, Write};
use std::path::Path;
use data_bundler;
#[cfg(windows)]
pub const NPM: &'static str = "npm.cmd";
#[cfg(not(windows))]
pub const NPM: &'static str = "npm";
// enum AndOr {
// And = 1,
// Or = 0,
// }
fn ensure_data_source(test_path: &std::path::PathBuf) {
if Path::new(&test_path).exists() {
println!("\nData source exists, skipping install.");
} else {
println!("\nData source not found, installing...");
std::process::Command::new("sh")
.arg("-c")
.arg(format!("{} i", NPM))
.status()
.expect("Unable to install data source");
}
}
fn repr_verse_path(verse_path: &scripture_types::VersePath) -> String {
match verse_path {
scripture_types::VersePath::PathBoM(a, b, c) => format!("VersePath::PathBoM({},{},{})", a, b, c),
scripture_types::VersePath::PathOT(a, b, c) => format!("VersePath::PathOT({},{},{})", a, b, c),
scripture_types::VersePath::PathNT(a, b, c) => format!("VersePath::PathNT({},{},{})", a, b, c),
scripture_types::VersePath::PathPOGP(a, b, c) => format!("VersePath::PathPOGP({},{},{})", a, b, c),
scripture_types::VersePath::PathDC(a, b) => format!("VersePath::PathDC({},{})", a, b),
}
}
pub fn read_file(filepath: &str) -> String {
let file = File::open(filepath).expect("could not open file");
let mut buffered_reader = BufReader::new(file);
let mut contents = String::new();
let _number_of_bytes: usize = match buffered_reader.read_to_string(&mut contents) {
Ok(number_of_bytes) => number_of_bytes,
Err(_err) => 0,
};
contents
}
pub fn copy_minified<T: serde::de::DeserializeOwned + serde::ser::Serialize>(
src_folder: &std::path::PathBuf,
dest_folder: &std::path::PathBuf,
file_name: &str,
) -> T {
println!(" {}", file_name);
let mut src = src_folder.clone();
src.push(file_name);
let unparsed: String = read_file(&src.into_os_string().into_string().unwrap());
let parsed: T = serde_json::from_str(&unparsed).unwrap();
let mut dest = dest_folder.clone();
dest.push(format!("{}.bin", file_name));
let mut f = BufWriter::new(File::create(dest).unwrap());
f.write(&bincode::serialize(&parsed).unwrap()).unwrap();
f.flush().unwrap();
parsed
}
pub fn write_minified<T: serde::ser::Serialize>(
data: &T,
dest_folder: &std::path::PathBuf,
file_name: &str,
) -> () {
let mut dest = dest_folder.clone();
dest.push(format!("{}.bin", file_name));
println!("writing {}", file_name);
let mut f = BufWriter::new(File::create(dest).unwrap());
f.write(&bincode::serialize(&data).unwrap()).unwrap();
f.flush().unwrap();
}
fn main() {
let mut project_root = std::env::current_exe().expect("Unable to find");
project_root.pop();
project_root.pop();
project_root.pop();
let mut src_folder = project_root.clone();
src_folder.push("node_modules");
src_folder.push("@bencrowder");
src_folder.push("scriptures-json");
let mut test_path = src_folder.clone();
test_path.push("old-testament.json");
ensure_data_source(&test_path);
let mut dest_folder = project_root.clone();
dest_folder.push("data-bundler");
dest_folder.push("data");
println!("Minifying:");
let ot = copy_minified::<scripture_types::OldTestament>(
&src_folder,
&dest_folder,
"old-testament.json",
);
let nt = copy_minified::<scripture_types::NewTestament>(
&src_folder,
&dest_folder,
"new-testament.json",
);
let bom = copy_minified::<scripture_types::BookOfMormon>(
&src_folder,
&dest_folder,
"book-of-mormon.json",
);
let dc = copy_minified::<scripture_types::DoctrineAndCovenants>(
&src_folder,
&dest_folder,
"doctrine-and-covenants.json",
);
let pogp = copy_minified::<scripture_types::PearlOfGreatPrice>(
&src_folder,
&dest_folder,
"pearl-of-great-price.json",
);
println!("Minifying done!\n");
println!("Building indices:");
let (words_index, paths_index) = data_bundler::build_index(&ot, &nt, &bom, &dc, &pogp);
println!("Index building done!\n");
println!("total word stems: {}", words_index.len());
println!("total paths: {}", paths_index.len());
write_minified(&paths_index, &dest_folder, "paths-index.json");
write_minified(&words_index, &dest_folder, "words-index.json");
let mut paths_index_codegen_file = dest_folder.clone();
paths_index_codegen_file.push("codegen-paths-index.rs");
println!("generating paths index codegen file...");
let mut paths_index_phf: phf_codegen::Map<u16> = phf_codegen::Map::new();
for (k, v) in &paths_index {
paths_index_phf.entry(*k, &repr_verse_path(v));
}
println!("writing paths index codegen file...");
let mut f_codegen = BufWriter::new(File::create(paths_index_codegen_file).unwrap());
writeln!(
&mut f_codegen,
"pub static PHF_PATHS_INDEX: phf::Map<u16, scripture_types::VersePath> = \n{};\n",
paths_index_phf.build(),
).unwrap();
let mut words_index_codegen_file = dest_folder.clone();
words_index_codegen_file.push("codegen-words-index.rs");
println!("generating words index codegen file...");
let mut words_index_phf: phf_codegen::Map<&str> = phf_codegen::Map::new();
for (word, usage_map) in &words_index {
let mut usages_phf: phf_codegen::Map<u16> = phf_codegen::Map::new();
for (scripture_id, highlights_vec) in usage_map {
let (i_s, l_s): (Vec<_>, Vec<_>) = highlights_vec.iter().cloned().map(|(x,y)| (x as u16, y as u8)).unzip();
usages_phf.entry(
*scripture_id,
&format!(
"(U256 {{ 0: {:?} }},{})",
data_bundler::pack_indices_arr(&i_s),
data_bundler::pack_lengths(&l_s),
),
);
}
let built_usages_phf = usages_phf.build();
words_index_phf.entry(word, &built_usages_phf.to_string());
}
println!("writing words index codegen file...");
let mut f_codegen_words_index = BufWriter::new(File::create(words_index_codegen_file).unwrap());
writeln!(
&mut f_codegen_words_index,
"pub static PHF_WORDS_INDEX: phf::Map<&str, phf::Map<u16, (U256,u128)>> = \n{};\n",
words_index_phf.build(),
).unwrap();
}