1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use clap::{App, Arg};

#[derive(Debug)]
pub struct Args {
    pub file_path: String,
    pub should_use_full_commit_hash: bool,
    pub beyond_last_line: bool,
    pub should_emphasize_diff: bool,
    pub user_for_name: UserType,
    pub user_for_date: UserType,
    pub date_format: String,
    pub tab_spaces: String,
}

#[derive(Debug)]
pub enum UserType {
    Author,
    Committer,
}

impl Args {
    pub fn load() -> Args {
        let matches = App::new(env!("CARGO_PKG_NAME"))
            .version(env!("CARGO_PKG_VERSION"))
            .about(env!("CARGO_PKG_DESCRIPTION"))
            .setting(clap::AppSettings::ColoredHelp)
            .arg(
                Arg::new("help")
                    .long("help")
                    .short('h')
                    .about("Print help information"),
            )
            .arg(
                Arg::new("version")
                    .long("version")
                    .short('v')
                    .about("Print version information"),
            )
            .arg(
                Arg::new("full-hash")
                    .long("full-hash")
                    .about("Show full commit hashes instead of abbreviated commit hashes"),
            )
            .arg(
                Arg::new("beyond-last-line")
                    .long("beyond-last-line")
                    .about("Set whether the view will scroll beyond the last line"),
            )
            .arg(
                Arg::new("emphasize-diff")
                    .long("emphasize-diff")
                    .about("Set whether the view will emphasize different parts"),
            )
            .arg(
                Arg::new("name-of")
                    .long("name-of")
                    .value_name("user")
                    .possible_values(&["author", "committer"])
                    .default_value("author")
                    .about("Use whether authors or committers for names"),
            )
            .arg(
                Arg::new("date-of")
                    .long("date-of")
                    .value_name("user")
                    .possible_values(&["author", "committer"])
                    .default_value("author")
                    .about("Use whether authors or committers for dates"),
            )
            .arg(
                Arg::new("date-format")
                    .long("date-format")
                    .value_name("format")
                    .default_value("[%Y-%m-%d]")
                    .about("Set date format: ref. https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html"),
            )
            .arg(
                Arg::new("tab-size")
                    .long("tab-size")
                    .value_name("size")
                    .default_value("4")
                    .about("Set the number of spaces for a tab character (\\t)")
            )
            .arg(
                Arg::new("file")
                    .about("Set a target file path")
                    .required(true),
            )
            .get_matches();

        let file_path = String::from(matches.value_of("file").unwrap());

        let should_use_full_commit_hash = matches.is_present("full-hash");
        let beyond_last_line = matches.is_present("beyond-last-line");
        let should_emphasize_diff = matches.is_present("emphasize-diff");
        let user_for_name = if matches.value_of("name-of").unwrap() == "author" {
            UserType::Author
        } else {
            UserType::Committer
        };
        let user_for_date = if matches.value_of("date-of").unwrap() == "author" {
            UserType::Author
        } else {
            UserType::Committer
        };
        let date_format = String::from(matches.value_of("date-format").unwrap());

        let tab_size = matches
            .value_of_t::<usize>("tab-size")
            .unwrap_or_else(|e| e.exit());
        let tab_spaces = " ".repeat(tab_size);

        Args {
            file_path,
            should_use_full_commit_hash,
            beyond_last_line,
            should_emphasize_diff,
            user_for_name,
            user_for_date,
            date_format,
            tab_spaces,
        }
    }
}