diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 46 |
1 files changed, 45 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs index dddbe42..9acc496 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,9 @@ extern crate reqwest; extern crate tokio; extern crate filters; +#[cfg(feature = "compare_csv")] +extern crate csv; + #[macro_use] extern crate serde_derive; #[macro_use] extern crate log; #[macro_use] extern crate failure; @@ -18,8 +21,13 @@ mod config; mod backend; mod frontend; mod cli; +mod compare; use std::path::PathBuf; + +#[cfg(feature = "compare_csv")] +use std::io::Cursor; + use failure::err_msg; use failure::Error; use failure::Fallible as Result; @@ -27,6 +35,7 @@ use clap::ArgMatches; use filters::filter::Filter; use config::Configuration; +use compare::ComparePackage; use librepology::v1::api::Api; use librepology::v1::types::Repo; @@ -57,6 +66,33 @@ fn initialize_logging(app: &ArgMatches) -> Result<()> { .map_err(Error::from) } +fn deserialize_package_list(s: String, filepath: &str) -> Result<Vec<ComparePackage>> { + let pb = PathBuf::from(filepath); + let ext = pb + .extension() + .ok_or_else(|| format_err!("Couldn't get file extension: {}", filepath))? + .to_str() + .ok_or_else(|| format_err!("Not valid Unicode: {}", filepath))?; + + match ext { + "json" => { + serde_json::from_str(&s).map_err(Error::from) + }, + + #[cfg(feature = "compare_csv")] + "csv" => { + let cursor = Cursor::new(s); + let mut v : Vec<ComparePackage> = vec![]; + for element in csv::Reader::from_reader(cursor).deserialize() { + v.push(element?); + } + Ok(v) + }, + + other => Err(format_err!("Unknown file extension: {}", other))?, + } +} + fn main() -> Result<()> { let app = cli::build_cli().get_matches(); initialize_logging(&app)?; @@ -145,7 +181,15 @@ fn main() -> Result<()> { .collect(); frontend.list_problems(problems)?; - } + }, + ("compare", Some(mtch)) => { + let repos = mtch.values_of("compare-distros").unwrap().map(|s| Repo::new(String::from(s))).collect(); + let file_path = mtch.value_of("compare-list").unwrap(); // safe by clap + let content = ::std::fs::read_to_string(file_path).map_err(Error::from)?; + let pkgs : Vec<ComparePackage> = deserialize_package_list(content, file_path)?; + + frontend.compare_packages(pkgs, &backend, repos)?; + }, (other, _mtch) => { if app.is_present("input_stdin") { |