jensmemesclient/cli/src/table.rs

82 lines
2 KiB
Rust

use chrono::{Local, TimeZone};
use comfy_table::{presets::UTF8_NO_BORDERS, ContentArrangement, Row, Table};
use libjens::api::{Category, Meme, User};
pub fn list_table() -> Table {
let mut table = Table::new();
table
.load_preset(UTF8_NO_BORDERS)
.set_content_arrangement(ContentArrangement::Dynamic);
table
}
pub trait TableHeader {
fn header() -> Row;
}
macro_rules! impl_table_header {
($t:ident, $e:expr) => {
impl TableHeader for $t {
fn header() -> Row {
$e.into()
}
}
};
}
impl_table_header!(User, vec!["Name", "ID"]);
impl_table_header!(Category, vec!["Name", "ID"]);
impl_table_header!(Meme, vec!["Link", "Category", "User", "Timestamp", "ID"]);
/// a newtype wrapper to convert libjens types to table rows
pub struct JMTableEntry<T>(pub T);
impl From<JMTableEntry<User>> for Row {
fn from(e: JMTableEntry<User>) -> Self {
vec![e.0.name, e.0.id.unwrap_or_else(String::new)].into()
}
}
impl From<JMTableEntry<Category>> for Row {
fn from(e: JMTableEntry<Category>) -> Self {
vec![e.0.name, e.0.id].into()
}
}
impl From<JMTableEntry<Meme>> for Row {
fn from(e: JMTableEntry<Meme>) -> Self {
vec![
e.0.link,
e.0.category,
e.0.user,
Local
.timestamp(e.0.timestamp, 0)
.format("%F %R")
.to_string(),
e.0.id,
]
.into()
}
}
pub trait TableExt {
fn add_rows<T: Into<Row>>(&mut self, iter: impl IntoIterator<Item = T>) -> &mut Self;
fn type_header<T: TableHeader>(&mut self) -> &mut Self;
}
impl TableExt for Table {
fn add_rows<T: Into<Row>>(&mut self, iter: impl IntoIterator<Item = T>) -> &mut Self {
for i in iter.into_iter() {
self.add_row(i);
}
self
}
fn type_header<T: TableHeader>(&mut self) -> &mut Self {
self.set_header(T::header())
}
}