Merge pull request #310 from matthiasbeyer/libimagentrylist/cli

Libimagentrylist/cli
This commit is contained in:
Matthias Beyer 2016-04-06 17:09:39 +02:00
commit 1fc7b64171
9 changed files with 141 additions and 9 deletions

View file

@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["Matthias Beyer <mail@beyermatthias.de>"] authors = ["Matthias Beyer <mail@beyermatthias.de>"]
[dependencies] [dependencies]
clap = "2.1.1"
log = "0.3.5" log = "0.3.5"
toml = "0.1.25" toml = "0.1.25"

View file

@ -0,0 +1,82 @@
use clap::{Arg, ArgMatches, App, SubCommand};
use libimagstore::store::FileLockEntry;
use result::Result;
use listers::line::LineLister;
use listers::path::PathLister;
use lister::Lister;
use error::{ListError, ListErrorKind};
pub fn build_list_cli_component<'a, 'b>() -> App<'a, 'b> {
SubCommand::with_name(list_subcommand_name())
.author("Matthias Beyer <mail@beyermatthias.de>")
.version("0.1")
.about("List entries")
.arg(Arg::with_name(list_backend_line())
.short("l")
.long("line")
.takes_value(false)
.required(false)
.multiple(false)
.help("Use backend: Line"))
.arg(Arg::with_name(list_backend_path())
.short("p")
.long("path")
.takes_value(false)
.required(false)
.multiple(false)
.help("Use backend: Path"))
.arg(Arg::with_name(list_backend_path_absolute())
.short("P")
.long("path-absolute")
.takes_value(false)
.required(false)
.multiple(false)
.help("Use backend: Path (absolute)"))
}
pub fn list_subcommand_name() -> &'static str {
"list"
}
pub fn list_backend_line() -> &'static str {
"line"
}
pub fn list_backend_path() -> &'static str {
"path"
}
pub fn list_backend_path_absolute() -> &'static str {
"path-absolute"
}
// TODO: Add Registry for listers where a HashMap name->lister is in and where we can fetch the
// lister from.
pub fn list_entries_with_lister<'a, I>(m: &ArgMatches, entries: I) -> Result<()>
where I: Iterator<Item = FileLockEntry<'a>>
{
if let Some(matches) = m.subcommand_matches(list_subcommand_name()) {
if matches.is_present(list_backend_line()) {
return LineLister::new("<unknown>").list(entries)
};
if matches.is_present(list_backend_path()) {
return PathLister::new(false).list(entries)
}
if matches.is_present(list_backend_path_absolute()) {
return PathLister::new(true).list(entries)
}
Ok(())
} else {
Err(ListError::new(ListErrorKind::CLIError, None))
}
}

View file

@ -10,7 +10,8 @@ use std::fmt::{Display, Formatter};
pub enum ListErrorKind { pub enum ListErrorKind {
FormatError, FormatError,
EntryError, EntryError,
IterationError IterationError,
CLIError,
} }
fn counter_error_type_as_str(err: &ListErrorKind) -> &'static str{ fn counter_error_type_as_str(err: &ListErrorKind) -> &'static str{
@ -18,6 +19,7 @@ fn counter_error_type_as_str(err: &ListErrorKind) -> &'static str{
&ListErrorKind::FormatError => "FormatError", &ListErrorKind::FormatError => "FormatError",
&ListErrorKind::EntryError => "EntryError", &ListErrorKind::EntryError => "EntryError",
&ListErrorKind::IterationError => "IterationError", &ListErrorKind::IterationError => "IterationError",
&ListErrorKind::CLIError => "No CLI subcommand for listing entries",
} }
} }

View file

@ -1,8 +1,10 @@
extern crate clap;
#[macro_use] extern crate log; #[macro_use] extern crate log;
extern crate toml; extern crate toml;
extern crate libimagstore; extern crate libimagstore;
pub mod cli;
pub mod error; pub mod error;
pub mod lister; pub mod lister;
pub mod listers; pub mod listers;

View file

@ -1,8 +1,10 @@
use clap::ArgMatches;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use result::Result; use result::Result;
pub trait Lister { pub trait Lister : Sized {
fn list<'a, I: Iterator<Item = FileLockEntry<'a>>>(&self, entries: I) -> Result<()>; fn list<'a, I: Iterator<Item = FileLockEntry<'a>>>(&self, entries: I) -> Result<()>;

View file

@ -0,0 +1,40 @@
use std::io::stdout;
use std::io::Write;
use std::ops::Deref;
use lister::Lister;
use result::Result;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;
pub struct CoreLister<'a> {
lister: &'a Fn(&Entry) -> String,
}
impl<'a> CoreLister<'a> {
pub fn new(lister: &'a Fn(&Entry) -> String) -> CoreLister<'a> {
CoreLister {
lister: lister,
}
}
}
impl<'a> Lister for CoreLister<'a> {
fn list<'b, I: Iterator<Item = FileLockEntry<'b>>>(&self, entries: I) -> Result<()> {
use error::ListError as LE;
use error::ListErrorKind as LEK;
entries.fold(Ok(()), |accu, entry| {
accu.and_then(|_| {
write!(stdout(), "{:?}\n", (self.lister)(entry.deref()))
.map_err(|e| LE::new(LEK::FormatError, Some(Box::new(e))))
})
})
}
}

View file

@ -1,22 +1,22 @@
use std::io::stdout; use std::io::stdout;
use std::io::Write; use std::io::Write;
use std::ops::Deref;
use cli::list_subcommand_name;
use lister::Lister; use lister::Lister;
use result::Result; use result::Result;
use clap::ArgMatches;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;
pub struct LineLister<'a> { pub struct LineLister<'a> {
lister: &'a Fn(&Entry) -> String, unknown_output: &'a str,
} }
impl<'a> LineLister<'a> { impl<'a> LineLister<'a> {
pub fn new(lister: &'a Fn(&Entry) -> String) -> LineLister<'a> { pub fn new(unknown_output: &'a str) -> LineLister<'a> {
LineLister { LineLister {
lister: lister, unknown_output: unknown_output,
} }
} }
@ -30,11 +30,11 @@ impl<'a> Lister for LineLister<'a> {
entries.fold(Ok(()), |accu, entry| { entries.fold(Ok(()), |accu, entry| {
accu.and_then(|_| { accu.and_then(|_| {
write!(stdout(), "{:?}\n", (self.lister)(entry.deref())) write!(stdout(), "{:?}\n",
entry.get_location().to_str().unwrap_or(self.unknown_output))
.map_err(|e| LE::new(LEK::FormatError, Some(Box::new(e)))) .map_err(|e| LE::new(LEK::FormatError, Some(Box::new(e))))
}) })
}) })
} }
} }

View file

@ -1,2 +1,3 @@
pub mod core;
pub mod line; pub mod line;
pub mod path; pub mod path;

View file

@ -2,9 +2,11 @@ use std::io::stdout;
use std::io::Write; use std::io::Write;
use std::ops::Deref; use std::ops::Deref;
use cli::list_subcommand_name;
use lister::Lister; use lister::Lister;
use result::Result; use result::Result;
use clap::ArgMatches;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
pub struct PathLister { pub struct PathLister {