summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <matthias.beyer@atos.net>2019-04-24 09:46:43 +0200
committerMatthias Beyer <matthias.beyer@atos.net>2019-04-24 09:58:51 +0200
commit4eb2b6a4544f0c2cfd0d72b1fac27bfb2882a4b4 (patch)
treed8e16647de4be6bbc2fb1378a327056d6428f792
parentdc43c56e3d7ef77c0b83289c6a8990be384ba8c9 (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.toml8
-rw-r--r--src/main.rs45
2 files changed, 52 insertions, 1 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 877701b..290c61a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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") {