scud 0.3.0

A secret library atm, woo woo.
use dialoguer::{
    FuzzySelect,
    theme::ColorfulTheme,
    Input,
    Confirm,
};

use colored::Colorize;

pub fn get_remaining_subject_length(commit_type: &str, scope: &str) -> usize {
    let max_subject_length = 100;

    let mut remaining_subject_length = max_subject_length - scope.len() - commit_type.len() - 2;

    if scope.len() > 0 {
      remaining_subject_length -= 2;
    }

    remaining_subject_length
}

pub fn get_commit_type() -> String {
  let commit_type_options = &[
      "feat:\tA new feature",
      "fix:\tA bug fix",
      "docs:\tDocumentation only changes",
      "style:\tChanges that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)",
      "refactor:\tA code change that neither fixes a bug nor adds a feature",
      "perf:\tA code change that improves performance",
      "test:\tAdding missing tests or correcting existing tests",
      "build:\tChanges that affect the build system or external dependencies (example scons, gulp, grunt, broccoli, npm, etc.)",
      "ci:\tChanges to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs, etc.)",
      "chore:\tOther changes that don't modify src/bin files",
      "revert:\tReverts a previous commit",
    ];

    let selected_commit_type = FuzzySelect::with_theme(&ColorfulTheme::default())
        .with_prompt("Select the type of change that you're committing:")
        .default(0)
        .items(&commit_type_options[..])
        .interact()
        .unwrap();

    commit_type_options[selected_commit_type].split(":").next().unwrap().to_string()
}

pub fn get_scope() -> String {
    Input::new()
      .with_prompt(
        format!("{}{}:{}", "What is the scope of this change ", "(e.g. component or file name)".yellow().bold(), " (press enter to skip)".black().bold())
      )
      .interact_text()
      .unwrap()
}

pub fn get_subject(commit_type: &str, scope: &str) -> String {
    let remaining_subject_length = get_remaining_subject_length(&commit_type, &scope);

    let subject: String = Input::new()
    .with_prompt(
      format!("{}{}{}{}:", "Write a short, imperative tense description of the change ", "(max ".yellow().bold(), remaining_subject_length.to_string().yellow().bold(), " chars)".yellow().bold())
    )
    .validate_with(|input: &String| -> Result<(), &str> {
        if input.len() <= remaining_subject_length {
            Ok(())
        } else {
            Err(
              // TODO: look into refactoring using thiserror
              // format!("{}{}\n{}{}{}{}\n\n", "Error:".red().bold(), "Provided subject exceeds character limit", "Expected: ".yellow().bold(),  "at most ", remaining_subject_length, " characters")
              // .to_string().as_str()
              "Provided subject exceeds character limit"
            )
        }
    })
    .default("".into())
    .interact_text().unwrap();

    subject
}

pub fn get_body() -> String {
  Input::new()
    .with_prompt(
      format!("{}:{}", "Provide a longer description of the change", " (press enter to skip)".black().bold())
    )
    .default("".into())
    .interact_text().unwrap()
}

pub fn get_breaking_changes() -> String {
    let breaking_changes = Confirm::with_theme(&ColorfulTheme::default())
        .with_prompt("Are there any breaking changes?")
        .default(false)
        .wait_for_newline(true)
        .interact()
        .unwrap();

    let mut breaking_changes_section = String::new();

    if breaking_changes {
      let breaking_changes_message: String = Input::new()
      .with_prompt(
        format!("{}", "Provide a description of the breaking changes")
      )
      .default("".into())
      .interact_text().unwrap();

      breaking_changes_section = format!("{}", breaking_changes_message)
    }

    breaking_changes_section
}

pub fn get_referenced_issues() -> String {
    let referenced_issues = Confirm::with_theme(&ColorfulTheme::default())
        .with_prompt("Does this change affect any open issues")
        .default(false)
        .wait_for_newline(true)
        .interact()
        .unwrap();

    let mut referenced_issues_section = String::new();

    if referenced_issues {
      let referenced_issues_message: String = Input::new()
      .with_prompt(
        format!("{}", r#"Add issue references (e.g. #193, #4892, etc.)"#)
      )
      .default("".into())
      .interact_text().unwrap();

      referenced_issues_section = format!("{}", referenced_issues_message)
    }

    referenced_issues_section
}