generate-readme 0.1.2

A command-line utlity to help you generate README.md files.
mod template;
mod ui;
mod utils;
mod config;
use std::path::PathBuf;

use clap::{arg, builder::styling, Command};

fn main() {
    config::load_user_config();
    let styles = styling::Styles::styled()
        .header(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
        .usage(styling::AnsiColor::Green.on_default() | styling::Effects::BOLD)
        .literal(styling::AnsiColor::Blue.on_default() | styling::Effects::BOLD)
        .placeholder(styling::AnsiColor::Cyan.on_default())
        .error(styling::AnsiColor::Red.on_default() | styling::Effects::BOLD);

    let cmd = Command::new("generate-readme")
        .version("0.1.1")
        .about("Generate README.md files from the terminal.")
        .styles(styles)
        .args([arg!(-t --"template-dir" <DIR> "Sets a custom directory for templates")])
        .get_matches();

    // prompt user to choose template type
    let mut template_type = ui::select(vec!["Standard", "Custom"], "Choose a template category", 0);

    // load templates based on type, default to standard if custom fails
    let templates = match template_type.as_str() {
        "Custom" => match template::load_custom_templates(
            // read custom template directory from command line args, default is ~/Documents/readme-templates
            match cmd.get_one::<String>("template-dir").map(String::as_str) {
                Some(t_dir) => PathBuf::from(t_dir),
                _ => dirs::document_dir().unwrap().join("readme-templates"),
            },
        ) {
            Ok(templates) => templates,
            Err(err) => {
                ui::message(Err(err));
                template_type = "Standard".to_string();
                template::load_standard_templates()
            }
        },
        _ => template::load_standard_templates(),
    };

    // prompt user to choose template
    let template_selection = ui::select(
        templates
            .iter()
            .map(|template| template.name.trim_end_matches(".md"))
            .collect(),
        format!("Choose a template from {}", template_type).as_str(),
        0,
    );

    // find template based on user selection
    let template = templates
        .iter()
        .find(|&template| template.name.starts_with(&template_selection))
        .unwrap();

    let section_blocks = &template.blocks;

    // prompt user to choose which sections to include
    let section_selection = ui::multi_select(
        &section_blocks
            .iter()
            .map(|block| block.name.as_str())
            .collect(),
        "Choose which sections to include (toggle using spacebar)",
        section_blocks
            .iter()
            .map(|block| block.required.clone())
            .collect(),
    );

    // output completed template
    template::write_file(template::fill_placeholders(
        section_selection
            .iter()
            .map(|&index| section_blocks[index].content.clone())
            .collect::<Vec<_>>()
            .join("\n"),
        template.placeholders.clone(),
    ));
}