use std::path::{Path, PathBuf};
use std::time::Instant;
use std::{env, fs, process};
use gbz_base::GBZBase;
use gbz_base::utils;
use simple_sds::binaries;
use getopts::Options;
fn main() -> Result<(), String> {
let start_time = Instant::now();
let config = Config::new();
if binaries::file_exists(&config.db_file) {
if config.overwrite {
eprintln!("Overwriting database {}", config.db_file.display());
fs::remove_file(&config.db_file).map_err(|x| x.to_string())?;
} else {
return Err(format!("Database {} already exists", config.db_file.display()));
}
}
GBZBase::create_from_files(config.gbz_file.as_ref(), config.chains_file(), &config.db_file)?;
let database = GBZBase::open(&config.db_file)?;
eprintln!("The graph contains {} nodes in {} chains with {} links",
database.nodes(), database.chains(), database.chain_links()
);
eprintln!("There are {} paths representing {} samples, {} haplotypes, and {} contigs",
database.paths(), database.samples(), database.haplotypes(), database.contigs()
);
let size = database.file_size().unwrap_or_else(|| String::from("unknown"));
eprintln!("Final database size: {}", size);
let end_time = Instant::now();
let seconds = end_time.duration_since(start_time).as_secs_f64();
eprintln!("Used {:.3} seconds", seconds);
utils::report_peak_memory_usage();
Ok(())
}
struct Config {
pub gbz_file: PathBuf,
pub chains_file: Option<PathBuf>,
pub db_file: PathBuf,
pub overwrite: bool,
}
impl Config {
pub fn new() -> Config {
let args: Vec<String> = env::args().collect();
let program = args[0].clone();
let mut opts = Options::new();
opts.optflag("h", "help", "print this help");
opts.optopt("c", "chains", "top-level chain file (optional)", "FILE");
opts.optopt("o", "output", "output file name (default: <input>.db)", "FILE");
opts.optflag("", "overwrite", "overwrite the database file if it exists");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => {
eprintln!("{}", f);
process::exit(1);
}
};
let chains_file = matches.opt_str("c").map(PathBuf::from);
let mut db_file: Option<PathBuf> = None;
if matches.opt_present("h") {
let header = format!("Usage: {} [options] graph.gbz", program);
eprint!("{}", opts.usage(&header));
process::exit(0);
}
if let Some(s) = matches.opt_str("o") {
db_file = Some(PathBuf::from(s));
}
let gbz_file = if let Some(s) = matches.free.first() {
PathBuf::from(s)
} else {
let header = format!("Usage: {} [options] graph.gbz", program);
eprint!("{}", opts.usage(&header));
process::exit(1);
};
if db_file.is_none() {
let mut name = gbz_file.clone();
name.add_extension("db");
db_file = Some(name);
}
let overwrite = matches.opt_present("overwrite");
Config {
gbz_file,
chains_file,
db_file: db_file.unwrap(),
overwrite,
}
}
fn chains_file(&self) -> Option<&Path> {
self.chains_file.as_ref().map(|x| x.as_ref())
}
}