use crate::entry::Entry;
use crate::Error;
use comfy_table::{Cell, ContentArrangement};
use leafslug_effects::files::is_json;
use std::path::PathBuf;
use time::formatting::Formattable;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct EntryDescription {
pub entry: Entry,
pub file_name: String,
}
impl TryFrom<PathBuf> for EntryDescription {
type Error = Error;
fn try_from(value: PathBuf) -> Result<Self, Self::Error> {
let file_name = value
.file_name()
.ok_or(Error::IsNotAFile)?
.to_str()
.ok_or(Error::FileNameHasInvalidCharacters)?
.to_owned();
Ok(Self {
entry: Entry::try_from(value).map_err(|e| {
Error::CouldNotDeserializeEntryFromJson(Box::new(e), file_name.clone())
})?,
file_name,
})
}
}
pub fn truncate_form(entry_description: &EntryDescription, truncate_at: usize) -> String {
let mut truncated_body = entry_description.entry.body.to_string();
truncated_body.truncate(truncate_at);
format!("{} -> {} ... ", entry_description.file_name, truncated_body)
}
pub fn table_list(
mut entry_list: impl Iterator<Item = EntryDescription>,
time_format_descriptor: &(impl Formattable + ?Sized),
) -> Result<String, Error> {
let mut table = comfy_table::Table::new();
table.load_preset(comfy_table::presets::NOTHING);
table.set_content_arrangement(ContentArrangement::Dynamic);
entry_list.try_fold((), |(), entry_desc| -> Result<(), Error> {
let bg_color = match entry_desc.entry.mood {
super::Mood::Good => comfy_table::Color::Green,
super::Mood::Bad => comfy_table::Color::Red,
super::Mood::Neutral => comfy_table::Color::White,
};
table.add_row(vec![
Cell::new((entry_desc.entry.at.format(time_format_descriptor)?).clone())
.bg(bg_color)
.fg(comfy_table::Color::Black),
Cell::new(format!("{}", &entry_desc.entry.body)).fg(bg_color),
]);
Ok(())
})?;
Ok(table.to_string())
}
pub fn book(value: &PathBuf) -> Result<impl Iterator<Item = EntryDescription>, Error> {
Ok(fs_extra::dir::get_dir_content(value)
.map_err(Error::DirCouldNotBeRead)?
.files
.into_iter()
.map(PathBuf::from)
.filter(is_json)
.flat_map(EntryDescription::try_from))
}