commit-formatter 0.1.0

A CLI tool to help you write git commit
Documentation
use dialoguer::{Confirm, Editor};
use std::fmt::{self, Display, Formatter};

#[derive(Copy, Clone)]
pub struct CommitType {
    text: &'static str,
    description: &'static str,
}

impl CommitType {
    pub fn default_commit_types() -> [CommitType; 8] {
        [
            CommitType {
                text: "feat",
                description: "A new feature"
            },
            CommitType {
                text: "fix",
                description: "A bug fix"
            },
            CommitType {
                text: "docs",
                description: "Documentation only changes"
            },
            CommitType {
                text: "style",
                description: "Changes that do not affect the meaning of the code(white-space, fomatting, missing semi-colons, etc)"
            },
            CommitType {
                text: "refactor",
                description: "A code change that neither fixes a bug or adds a feature"
            },
            CommitType {
                text: "perf",
                description: "A code change that improves performance"
            },
            CommitType {
                text: "test",
                description: "Adding missing tests"
            },
            CommitType {
                text: "chore",
                description: "Change to the build process or auxiliary tools and libraries such as documentation generation"
            },
        ]
    }
}

impl Display for CommitType {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{:9}: {}", self.text, self.description)
    }
}

pub fn get_optional_commit_body_and_footer() -> Option<String> {
    let should_open_editor =  Confirm::new()
        .with_prompt("Do you want to write a long description?")
        .default(false)
        .show_default(false)
        .interact()
        .unwrap();
    if should_open_editor {
        return Editor::new()
            .edit("")
            .unwrap();
    }
    None
}

pub fn put_together_commit_message(
    commit_type: CommitType,
    scope: String,
    subject: String,
    optional_body_and_footer: Option<String>
) -> String {
    let mut format_commit_message = commit_type.text.to_string();
    if scope.is_empty() {
        format_commit_message.push_str(": ");
    } else {
        format_commit_message.push_str(&format!("({}): ", scope));
    }
    format_commit_message.push_str(&subject);
    if let Some(text) = optional_body_and_footer {
        format_commit_message.push_str(&format!("\n\n{}", text));
    }
    format_commit_message
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_commit_to_string() {
        let fix = CommitType {
            text: "fix",
            description: "just for test"
        };
        assert_eq!(fix.to_string(), "fix      : just for test");
    }

    #[test]
    fn test_composite_commit() {
        let bug = CommitType {
            text: "bug",
            description: "a test"
        };
        let scope = String::from("view");
        let subject = String::from("test example");
        let other: Option<String> = None;
        let result = put_together_commit_message(bug, scope, subject, other);
        assert_eq!(result, String::from("bug(view): test example"))
    }
}