leafslug_jnl 0.4.0

A personal journaling system that is not inteded to be used by others... yet.
Documentation
use super::{EntryDescription, Result};
use crate::entry::Entry;
use crate::{table_list, Error};
use leafslug_effects::files::ToFileName;
use leafslug_effects::{self, create_dir, write_to_file};

use std::path::{Path, PathBuf};
use time::formatting::Formattable;
use time::OffsetDateTime;

pub fn new_entry(
    entry: &Entry,
    journal_path: &PathBuf,
    repo_root: &str,
    at: OffsetDateTime,
    time_format_descriptor_for_file_name: &(impl Formattable + ?Sized),
) -> Result<()> {
    let file_name = at.to_file_name(time_format_descriptor_for_file_name)?;
    let file_path = journal_path.join(&file_name);
    let fp = file_path.to_string_lossy().into_owned();
    let content = serde_json::to_string_pretty(&entry)
        .map_err(|e| Error::FileCouldNotSerializeEntryIntoJson(e, file_name.clone()))?
        .as_bytes()
        .to_vec();

    create_dir(journal_path.to_owned(), true)?;
    write_to_file(content, &file_path, true, false)?;

    leafslug_effects::git_add(repo_root, [fp])?;
    leafslug_effects::git_commit(
        repo_root,
        &format!("feat(journal): add new journal entry {file_name}"),
    )?;
    leafslug_effects::git_pull(repo_root)?;
    leafslug_effects::git_push(repo_root)?;

    Ok(())
}

pub fn list_entries(
    book: impl Iterator<Item = EntryDescription>,
    time_format_descriptor: &(impl Formattable + ?Sized),
) -> Result<()> {
    println!("{}", table_list(book, time_format_descriptor)?);
    Ok(())
}

pub fn edit_last_entry(
    journal_path: &Path,
    book: impl Iterator<Item = EntryDescription>,
    repo_root: &str,
    editor: String,
) -> Result<()> {
    let last_entry = &book.last().ok_or(Error::NoEntries)?;
    let file_name = &last_entry.file_name;
    let ent_path = journal_path.join(file_name);
    let fp = ent_path.to_string_lossy().into_owned();

    leafslug_effects::open_in_editor(editor, [&ent_path])?;
    leafslug_effects::git_add(repo_root, [fp])?;
    leafslug_effects::git_commit(
        repo_root,
        &format!("feat(journal): edit the entry {file_name}"),
    )?;
    leafslug_effects::git_pull(repo_root)?;
    leafslug_effects::git_push(repo_root)?;

    Ok(())
}

pub fn edit_specific_entry(
    journal_path: &Path,
    specifier: &str,
    book: impl Iterator<Item = EntryDescription>,
    repo_root: &str,
    editor: String,
) -> Result<()> {
    let ent_path: Vec<PathBuf> = book
        .filter(|x| x.file_name.contains(specifier))
        .map(|ent| journal_path.join(ent.file_name))
        .collect();
    leafslug_effects::open_in_editor(editor, ent_path.iter())?;
    let fp = ent_path
        .into_iter()
        .map(|x| Path::to_string_lossy(&x).into_owned());

    leafslug_effects::git_add(repo_root, fp)?;
    leafslug_effects::git_commit(repo_root, "feat(journal): edit the few entries")?;
    leafslug_effects::git_pull(repo_root)?;
    leafslug_effects::git_push(repo_root)?;

    Ok(())
}

// pub fn delete_interactive(
//     journal_path: &PathBuf,
//     truncation_amount: usize,
//     book: Book,
//     time_format_descriptor_for_displaying: &(impl Formattable + ?Sized),
// ) -> Result<()> {
//     let options: Vec<String> = book.truncated_form(truncation_amount);

//     let selection = FuzzySelect::with_theme(&ColorfulTheme::default())
//         .with_prompt("which file")
//         .items(&options)
//         .interact()
//         .map_err(Error::DialoguerError)?;

//     println!("\n{}", "This is the selected item:".bold().red());

//     let selected = book
//         .entries
//         .get(selection)
//         .ok_or(Error::EntryCouldNotBeFound)?;

//     println!(
//         "{}\n",
//         selected
//             .entry
//             .pretty_formated(time_format_descriptor_for_displaying)?
//     );

//     if Confirm::with_theme(&ColorfulTheme::default())
//         .with_prompt(format!(
//             "Are you {} you want to {} the above entry?",
//             "absolutely sure".bold().red(),
//             "delete".bold().red()
//         ))
//         .default(false)
//         .interact()
//         .map_err(Error::DialoguerError)?
//     {
//         let file_path = journal_path.join(&selected.file_name);
//         fs_extra::remove_items(&[file_path]).map_err(Error::FileCouldNotBeDeleted)?;
//     };

//     Ok(())
// }
pub fn edit_all_entries(
    editor: String,
    book: impl Iterator<Item = EntryDescription>,
    repo_root: &str,
    notes_dir: &Path,
) -> Result<()> {
    leafslug_effects::open_in_editor_owned(
        editor,
        book.map(|entry_description| notes_dir.join(entry_description.file_name)),
    )?;
    leafslug_effects::git_add(repo_root, [repo_root.to_owned()])?;
    leafslug_effects::git_commit(repo_root, "feat(journal): edit the few entries")?;
    leafslug_effects::git_pull(repo_root)?;
    leafslug_effects::git_push(repo_root)?;

    Ok(())
}