term-header/src/config.rs

112 lines
3.5 KiB
Rust

//! Logic to define and parse a configuration from command line arguments.
use clap::Parser;
use colored::Color;
/// Contains all the arguments parsed from the command line.
///
/// # Fields
///
/// - `titles_path`: Specifies the path to the ASCII text files directory. If not provided, assumes the directory is in the current directory.
/// - `art_path`: Specifies the path to the ASCII image files directory. If not provided, assumes the directory is in the current directory.
/// - `banner_path`: Specifies the path to the ASCII banner file. If not provided, assumes the file is in the current directory.
/// - `color`: Specifies the color to output the terminal header as. If not provided, outputs as normal.
///
/// # Examples
/// ```
/// use clap::Parser;
/// use term_header::config;
///
/// let args = config::Args::parse();
///
/// assert_eq!(args.titles_path, "./titles/");
/// assert_eq!(args.art_path, "./art/");
/// assert_eq!(args.banner_path, "./banner.txt");
/// assert_eq!(args.color, None);
/// ```
#[derive(Parser, Debug)]
#[command(
name = "term-header",
author = "r0r-5chach",
version = "1.0",
about = "A program that generates ASCII art terminal headers.
color can cause unexpected behaviour when used with terminal themes.",
long_about = None)]
pub struct Args {
/// The path to the ASCII text files directory
#[arg(short, long, default_value = "./titles/")]
pub titles_path: String,
/// The path to the ASCII image files directory
#[arg(short, long, default_value = "./art/")]
pub art_path: String,
/// The path to the ASCII banner
#[arg(short, long, default_value = "./banner.txt")]
pub banner_path: String,
/// The color the text should be outputed as (Terminal themes can cause unexpected behaviour)
#[arg(short, long, default_value = None)]
pub color: Option<Color>,
}
/// Contains the configuration for the program.
///
/// # Fields
/// - `title_file`: The contents of the randomly selected ASCII text file.
/// - `art_file`: The contents of the randomly selected ASCII image file.
/// - `banner_file`: The contents of the randomly selected ASCII banner file.
///
pub struct Config {
pub title_file: String,
pub art_file: String,
pub banner_file: String,
pub color: Option<Color>,
}
impl Config {
/// Returns a new configuration parsed from the [Args] parsed from the command line.
pub fn new(args: Args) -> Self { //TODO: Add examples using tempdir to create a dir
let title_file = rand_file_from_path(args.titles_path);
let art_file = rand_file_from_path(args.art_path);
let banner_file = args.banner_path;
let color = args.color;
Self {
title_file,
art_file,
banner_file,
color,
}
}
}
fn get_file_count(dir: &str) -> usize {
use std::fs;
let files = match fs::read_dir(&dir) {
Ok(files) => files,
Err(_) => path_not_found_error(&dir),
};
files.count()
}
fn rand_file_from_path(path: String) -> String {
use rand::Rng;
let mut rng = rand::thread_rng();
let mut file = path.clone();
let file_count = get_file_count(&path);
match file_count {
count if count < 2 => file.push_str("1"),
_ => file.push_str(&rng.gen_range(1..get_file_count(&path)).to_string()),
}
file.push_str(".txt");
file.to_string()
}
fn path_not_found_error(path: &str) -> ! {
eprintln!("This path does not exist: {}", path);
std::process::exit(1);
}