use std::path::{Path, PathBuf};
use serde::de::DeserializeOwned;
use crate::io::LineProcessor;
use crate::openlib::*;
use crate::prelude::*;
use crate::util::logging::data_progress;
use super::Command;
#[derive(Args, Debug)]
struct Input {
#[arg(name = "INPUT")]
infile: PathBuf,
}
#[derive(clap::Subcommand, Debug)]
enum DataType {
ScanWorks(Input),
ScanEditions(Input),
ScanAuthors(Input),
}
#[derive(Args, Debug)]
#[command(name = "openlib")]
pub struct OpenLib {
#[command(subcommand)]
mode: DataType,
}
fn scan_openlib<R, Proc>(path: &Path, proc: Proc) -> Result<()>
where
Proc: ObjectWriter<Row<R>>,
R: DeserializeOwned,
{
let mut proc = proc;
let mut nlines = 0;
info!("opening file {}", path.to_string_lossy());
let pb = data_progress(0);
let input = LineProcessor::open_gzip(path, pb.clone())?;
for line in input.records() {
nlines += 1;
if !line.is_ok() {
error!("parse error on line {}", nlines);
}
let row: Row<R> = line?;
proc.write_object(row)?;
}
proc.finish()?;
Ok(())
}
impl Command for OpenLib {
fn exec(&self) -> Result<()> {
match &self.mode {
DataType::ScanAuthors(opts) => {
scan_openlib(&opts.infile, AuthorProcessor::new()?)?;
}
DataType::ScanWorks(opts) => {
scan_openlib(&opts.infile, WorkProcessor::new()?)?;
}
DataType::ScanEditions(opts) => {
scan_openlib(&opts.infile, EditionProcessor::new()?)?;
}
};
Ok(())
}
}