use std::fmt;
use std::fs::File;
use std::io;
use std::path::Path;
use std::time;
use csv;
use fst;
use memmap::Mmap;
use crate::error::{Error, ErrorKind, Result};
pub const IMDB_BASICS: &str = "title.basics.tsv";
pub const IMDB_AKAS: &str = "title.akas.tsv";
pub const IMDB_EPISODE: &str = "title.episode.tsv";
pub const IMDB_RATINGS: &str = "title.ratings.tsv";
#[derive(Debug)]
pub struct NiceDuration(pub time::Duration);
impl fmt::Display for NiceDuration {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:0.4} secs", self.fractional_seconds())
}
}
impl NiceDuration {
pub fn since(t: time::Instant) -> NiceDuration {
NiceDuration(time::Instant::now().duration_since(t))
}
pub fn fractional_seconds(&self) -> f64 {
let fractional = (self.0.subsec_nanos() as f64) / 1_000_000_000.0;
self.0.as_secs() as f64 + fractional
}
}
pub fn csv_reader_builder() -> csv::ReaderBuilder {
let mut builder = csv::ReaderBuilder::new();
builder.has_headers(true).delimiter(b'\t').quoting(false);
builder
}
pub unsafe fn csv_mmap<P: AsRef<Path>>(
path: P,
) -> Result<csv::Reader<io::Cursor<Mmap>>> {
let mmap = mmap_file(path)?;
Ok(csv_reader_builder().from_reader(io::Cursor::new(mmap)))
}
pub fn csv_file<P: AsRef<Path>>(path: P) -> Result<csv::Reader<File>> {
let path = path.as_ref();
let rdr = csv_reader_builder().from_path(path).map_err(|e| {
Error::new(ErrorKind::Csv(format!("{}: {}", path.display(), e)))
})?;
Ok(rdr)
}
pub unsafe fn mmap_file<P: AsRef<Path>>(path: P) -> Result<Mmap> {
let path = path.as_ref();
let file = open_file(path)?;
let mmap = Mmap::map(&file).map_err(|e| Error::io_path(e, path))?;
Ok(mmap)
}
pub fn create_file<P: AsRef<Path>>(path: P) -> Result<File> {
let path = path.as_ref();
let file = File::create(path).map_err(|e| Error::io_path(e, path))?;
Ok(file)
}
pub fn open_file<P: AsRef<Path>>(path: P) -> Result<File> {
let path = path.as_ref();
let file = File::open(path).map_err(|e| Error::io_path(e, path))?;
Ok(file)
}
pub fn fst_set_builder_file<P: AsRef<Path>>(
path: P,
) -> Result<fst::SetBuilder<io::BufWriter<File>>> {
let path = path.as_ref();
let wtr = io::BufWriter::new(create_file(path)?);
let builder = fst::SetBuilder::new(wtr).map_err(|e| {
Error::new(ErrorKind::Fst(format!("{}: {}", path.display(), e)))
})?;
Ok(builder)
}
pub unsafe fn fst_set_file<P: AsRef<Path>>(path: P) -> Result<fst::Set<Mmap>> {
let path = path.as_ref();
let file = File::open(path).map_err(|e| Error::io_path(e, path))?;
let mmap = Mmap::map(&file).map_err(|e| Error::io_path(e, path))?;
let set = fst::Set::new(mmap).map_err(|e| {
Error::new(ErrorKind::Fst(format!("{}: {}", path.display(), e)))
})?;
Ok(set)
}
pub fn fst_map_builder_file<P: AsRef<Path>>(
path: P,
) -> Result<fst::MapBuilder<io::BufWriter<File>>> {
let path = path.as_ref();
let wtr = io::BufWriter::new(create_file(path)?);
let builder = fst::MapBuilder::new(wtr).map_err(|e| {
Error::new(ErrorKind::Fst(format!("{}: {}", path.display(), e)))
})?;
Ok(builder)
}
pub unsafe fn fst_map_file<P: AsRef<Path>>(path: P) -> Result<fst::Map<Mmap>> {
let path = path.as_ref();
let file = File::open(path).map_err(|e| Error::io_path(e, path))?;
let mmap = Mmap::map(&file).map_err(|e| Error::io_path(e, path))?;
let map = fst::Map::new(mmap).map_err(|e| {
Error::new(ErrorKind::Fst(format!("{}: {}", path.display(), e)))
})?;
Ok(map)
}