diff options
author | Matthias Beyer <matthias.beyer@atos.net> | 2019-04-24 09:46:43 +0200 |
---|---|---|
committer | Matthias Beyer <matthias.beyer@atos.net> | 2019-04-24 09:58:51 +0200 |
commit | 4eb2b6a4544f0c2cfd0d72b1fac27bfb2882a4b4 (patch) | |
tree | d8e16647de4be6bbc2fb1378a327056d6428f792 | |
parent | dc43c56e3d7ef77c0b83289c6a8990be384ba8c9 (diff) |
Add "compare" functionality in main()
Including the new dependency "csv" which is included by default.
With this, one can pass a CSV file to compare against, as well as a JSON
file.
-rw-r--r-- | Cargo.toml | 8 | ||||
-rw-r--r-- | src/main.rs | 45 |
2 files changed, 52 insertions, 1 deletions
@@ -26,3 +26,11 @@ filters = "0.3" version = ">=2.33" default-features = false features = [ "suggestions", "color", "wrap_help" ] + +[dependencies.csv] +version = "1" +optional = true + +[features] +default = ["compare_csv"] +compare_csv = ["csv"]
\ No newline at end of file diff --git a/src/main.rs b/src/main.rs index dddbe42..62e193d 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; @@ -20,6 +23,10 @@ mod frontend; mod cli; use std::path::PathBuf; + +#[cfg(feature = "compare_csv")] +use std::io::Cursor; + use failure::err_msg; use failure::Error; use failure::Fallible as Result; @@ -29,6 +36,7 @@ use filters::filter::Filter; use config::Configuration; use librepology::v1::api::Api; use librepology::v1::types::Repo; +use librepology::v1::types::Package; fn initialize_logging(app: &ArgMatches) -> Result<()> { let verbosity = app.occurrences_of("verbose"); @@ -57,6 +65,33 @@ fn initialize_logging(app: &ArgMatches) -> Result<()> { .map_err(Error::from) } +fn deserialize_package_list(s: String, filepath: &str) -> Result<Vec<Package>> { + 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<Package> = 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 +180,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<Package> = deserialize_package_list(content, file_path)?; + + frontend.compare_packages(pkgs, &backend, repos)?; + }, (other, _mtch) => { if app.is_present("input_stdin") { |