use clap::ArgMatches; use failure::Fallible as Result; use librepology::v1::api::Api; use librepology::v1::restapi::RestApi; use librepology::v1::stdinapi::StdinWrapper; use librepology::v1::types::*; use crate::config::Configuration; /// Helper type for cli implementation /// for being transparent in what backend we use pub enum Backend { Stdin(StdinWrapper), RepologyOrg(RestApi), } /// Implement Api for Backend /// /// With this, we can use the `Backend` object and do not have to care whether we have a librepology:: impl Api for Backend { fn project>(&self, name: N) -> Result> { match self { Backend::Stdin(inner) => inner.project(name), Backend::RepologyOrg(inner) => inner.project(name), } } fn problems_for_repo>(&self, repo: R) -> Result> { match self { Backend::Stdin(inner) => inner.problems_for_repo(repo), Backend::RepologyOrg(inner) => inner.problems_for_repo(repo), } } fn problems_for_maintainer>(&self, maintainer: M) -> Result> { match self { Backend::Stdin(inner) => inner.problems_for_maintainer(maintainer), Backend::RepologyOrg(inner) => inner.problems_for_maintainer(maintainer), } } } pub fn new_backend(app: &ArgMatches, config: &Configuration) -> Result { if app.is_present("input_stdin") { Ok(Backend::Stdin(StdinWrapper::from(::std::io::stdin()))) } else { debug!("Constructing backend"); let url = config.repology_url().as_str().into(); trace!("url = {}", url); Ok(Backend::RepologyOrg(RestApi::new(url))) } }