refactor, fix filters, add column renaming, general fixes

This commit is contained in:
JMARyA 2023-10-26 09:41:18 +02:00
parent d12637ce75
commit d8ce9df7bc
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
5 changed files with 368 additions and 135 deletions

View file

@ -10,7 +10,7 @@ pub fn get_args() -> ArgMatches {
.arg(
arg!(-c --column <COLUMN>... "Specify output columns")
.required(false)
.default_value("path"),
.default_value("file.title:Title"),
)
.get_matches()
}

View file

@ -66,7 +66,15 @@ fn get_key(d: &Document, key: &str) -> String {
}
if let Some(val) = d.frontmatter.as_mapping().unwrap().get(key) {
// TODO : Fix format
format!("{val:?}")
match val {
serde_yaml::Value::Null => String::new(),
serde_yaml::Value::Bool(b) => b.to_string(),
serde_yaml::Value::Number(n) => n.to_string(),
serde_yaml::Value::String(s) => s.to_owned(),
serde_yaml::Value::Sequence(_v) => todo!(),
serde_yaml::Value::Mapping(_o) => todo!(),
serde_yaml::Value::Tagged(_) => unimplemented!(),
}
} else {
String::new()
}
@ -76,7 +84,7 @@ type Table = Vec<Vec<String>>;
/// Build a table with specified columns from index
#[must_use]
pub fn select_columns(i: &Index, col: &[&String]) -> Table {
pub fn select_columns(i: &Index, col: &[String]) -> Table {
let mut rows = vec![];
for doc in &i.documents {
@ -93,21 +101,40 @@ pub fn select_columns(i: &Index, col: &[&String]) -> Table {
/// Apply filters to the documents of the index returning a new filtered index
#[must_use]
pub fn filter_documents(i: Index, filters: &[txd::filter::Filter]) -> Index {
// TODO : Implement option for chaining filters with AND OR
let docs: Vec<_> = i
.documents
.into_iter()
.filter_map(|x| {
for f in filters {
let a = get_key(&x, &f.0);
let mut is_included = true;
let a = txd::parse(&a);
for f in filters {
let a_str = get_key(&x, &f.0);
let mut a = txd::parse(&a_str);
let b = txd::parse(&f.2);
if a.compare(f.1, b) {
return Some(x);
log::debug!("Trying to compare {a:?} and {b:?} with {:?}", f.1);
if a_str.is_empty() {
// TODO : Maybe add explicit null instead of empty string
is_included = false;
break;
}
if !a.same_as(&b) {
log::debug!("trying to cast a to string because of different types");
a = txd::DataType::String(a_str);
}
if !a.compare(f.1, b) {
is_included = false
}
}
None
if is_included {
Some(x)
} else {
None
}
})
.collect();

View file

@ -1,11 +1,16 @@
use std::io::IsTerminal;
use mdq::{filter_documents, scan_dir, select_columns};
use prettytable::{Cell, Row};
mod args;
// TODO : Add debug logging
// TODO : Add documentation comments
// TODO : Add tests
fn main() {
env_logger::init();
let args = args::get_args();
//println!("{args:?}");
let root_dir = args.get_one::<String>("dir").unwrap();
@ -17,11 +22,24 @@ fn main() {
None
};
let columns: Vec<_> = if let Some(columns) = args.get_many::<String>("column") {
columns.collect()
} else {
vec![]
};
let columns: Vec<_> = args
.get_many::<String>("column")
.unwrap()
.cloned()
.collect();
log::info!("selected columns: {columns:?}");
let columns: Vec<(_, _)> = columns
.into_iter()
.map(|x| {
let (column, header_rename) = x.split_once(':').unwrap_or((&x, &x));
(column.to_owned(), header_rename.to_owned())
})
.collect();
let (columns, headers): (Vec<_>, Vec<_>) = columns.into_iter().unzip();
let filters: Vec<_> = if let Some(filters) = args.get_many::<String>("filter") {
filters.collect()
} else {
@ -48,30 +66,34 @@ fn main() {
};
if output_json {
let data = serde_json::json!(
let mut data = serde_json::json!(
{
"columns": columns,
"results": data
}
);
if columns != headers {
data.as_object_mut()
.unwrap()
.insert("headers".into(), headers.into());
}
println!("{}", serde_json::to_string(&data).unwrap());
return;
}
let mut table = prettytable::Table::new();
let headers = columns
.iter()
.map(|cell| Cell::new(cell))
.collect::<Vec<Cell>>();
table.set_titles(Row::new(headers));
// Add rows to the table
for row in data {
let cells: Vec<Cell> = row.iter().map(|cell| Cell::new(cell)).collect();
table.add_row(Row::new(cells));
if data.is_empty() {
return;
}
// Print the table to the console
table.printstd();
let mut table = comfy_table::Table::new();
table.set_header(headers);
table.load_preset(comfy_table::presets::UTF8_FULL_CONDENSED);
if !std::io::stdout().is_terminal() {
// TODO : Output as CSV?
table.load_preset(comfy_table::presets::NOTHING);
}
table.add_rows(data);
println!("{table}");
}