use std::collections::HashMap;
use std::str;
use anyhow::{Context, Result};
use clap::ArgMatches;
use rucksack_db::records;
use rucksack_lib::file;
use crate::app::App;
use crate::output::{option, result, table};
pub fn backup_dir(_matches: &ArgMatches, app: &App) -> Result<()> {
println!("\n{}\n", app.backup_dir());
Ok(())
}
pub fn config_file(_matches: &ArgMatches, app: &App) -> Result<()> {
println!("\n{}\n", app.inputs.config_file());
Ok(())
}
pub fn config(_matches: &ArgMatches, app: &App) -> Result<()> {
let bytes = file::read(app.inputs.config_file())
.with_context(|| format!("failed to read config file '{}'", app.inputs.config_file()))?;
let config_str =
str::from_utf8(bytes.as_ref()).context("config file contains invalid UTF-8")?;
println!("\n{}", config_str);
Ok(())
}
pub fn data_dir(_matches: &ArgMatches, app: &App) -> Result<()> {
println!("\n{}\n", app.data_dir());
Ok(())
}
pub fn db_file(_matches: &ArgMatches, app: &App) -> Result<()> {
println!("\n{}\n", app.db_file());
Ok(())
}
pub fn db_version(_matches: &ArgMatches, app: &App) -> Result<()> {
println!("\n{}\n", app.db_version());
Ok(())
}
pub fn categories(_matches: &ArgMatches, app: &App) -> Result<()> {
let mut results: HashMap<String, bool> = HashMap::new();
for i in app.db.iter() {
let dr = records::decrypt_versioned(
i.value(),
app.db.store_pwd(),
app.inputs.salt(),
app.db.version(),
)
.with_context(|| format!("failed to decrypt record '{}'", i.key()))?;
results.insert(dr.metadata().category, true);
}
let mut cats: Vec<&String> = results.keys().clone().collect();
cats.sort();
let mut results: Vec<result::ResultRow> = Vec::new();
for c in cats {
results.push(result::category(c.to_string()))
}
let mut opts = option::defaults();
opts.categories = true;
let mut t = table::new(results.to_owned(), opts);
t.display();
println!();
Ok(())
}
pub fn tags(_matches: &ArgMatches, app: &App) -> Result<()> {
let mut results: HashMap<String, bool> = HashMap::new();
for i in app.db.iter() {
let dr = records::decrypt_versioned(
i.value(),
app.db.store_pwd(),
app.inputs.salt(),
app.db.version(),
)
.with_context(|| format!("failed to decrypt record '{}'", i.key()))?;
for t in dr.metadata().tags {
results.insert(t.display_or_value(), true);
}
}
let mut tags: Vec<&String> = results.keys().clone().collect();
tags.sort();
let mut results: Vec<result::ResultRow> = Vec::new();
for t in tags {
results.push(result::tag(t.to_string()))
}
let mut opts = option::defaults();
opts.tags = true;
let mut t = table::new(results.to_owned(), opts);
t.display();
println!();
Ok(())
}
pub fn types(_matches: &ArgMatches, _app: &App) -> Result<()> {
let mut results: Vec<result::ResultRow> = Vec::new();
for t in records::types() {
results.push(result::kind(t))
}
let mut opts = option::defaults();
opts.kinds = true;
let mut t = table::new(results.to_owned(), opts);
t.display();
println!();
Ok(())
}