notebook_rs/
argparse.rs

1use crate::{text_from_editor, Args, Entry};
2use clap::{Arg, ArgMatches, Command};
3
4pub fn get_args() -> ArgMatches {
5    Command::new("Notebook")
6        .about("CLI utility for plaintext notetaking.")
7        .subcommand_required(true)
8        .arg_required_else_help(true)
9        .subcommand(
10            Command::new("new")
11                .short_flag('n')
12                .long_flag("new")
13                .about("Create a new note")
14                .arg(Arg::new("entry")),
15        )
16        .arg(
17            Arg::new("notebook_name")
18                .short('j')
19                .long("notebook")
20                .default_value("default")
21                .help("Specify a notebook name"),
22        )
23        .subcommand(
24            Command::new("list")
25                .short_flag('l')
26                .long_flag("list")
27                .about("List entries")
28                .arg(Arg::new("list").default_value("5")),
29        )
30        .arg(
31            Arg::new("verbose")
32                .short('v')
33                .long("verbose")
34                .help("Quantity of information")
35                .action(clap::ArgAction::Count),
36        )
37        .subcommand(
38            Command::new("edit")
39                .short_flag('e')
40                .long_flag("edit")
41                .about("Edit specific entry")
42                .arg(Arg::new("edit")),
43        )
44        .subcommand(
45            Command::new("read")
46                .short_flag('r')
47                .long_flag("read")
48                .about("Display specific entry")
49                .arg(Arg::new("read")),
50        )
51        .subcommand(
52            Command::new("delete")
53                .short_flag('X')
54                .long_flag("delete")
55                .about("Delete specific entry")
56                .arg(Arg::new("delete")),
57        )
58        .subcommand(
59            Command::new("date search")
60                .short_flag('d')
61                .long_flag("date-search")
62                .about("Search for entries around a date")
63                .arg(Arg::new("datesearch")),
64        )
65        .subcommand(
66            Command::new("search")
67                .short_flag('s')
68                .long_flag("search")
69                .about("Query to search, enclosed in quotations")
70                .arg(Arg::new("search"))
71                .subcommand(
72                    Command::new("date")
73                        .short_flag('d')
74                        .long_flag("date")
75                        .about("Filter results by date range")
76                        .arg(Arg::new("entry")),
77                ),
78        )
79        .arg(
80            Arg::new("config")
81                .short('c')
82                .long("config")
83                .help("Path of config file to read"),
84        )
85        .get_matches()
86}
87
88pub fn parse_args(matches: ArgMatches, dt_format: &str) -> Args {
89    let verbose = matches.get_count("verbose");
90
91    match matches.subcommand() {
92        Some(("new", input)) => {
93            let text: String = match input.get_many::<String>("entry") {
94                Some(t) => t.fold(String::new(), |mut a, b| {
95                    a.reserve(b.len() + 1);
96                    a.push_str(b);
97                    a.push(' ');
98                    a
99                }),
100
101                None => text_from_editor(None).unwrap(),
102            };
103            let e = Entry::new(text, dt_format);
104            Args::New(e)
105        }
106
107        Some(("list", input)) => {
108            let n: usize = input.get_one::<String>("list").unwrap().parse().unwrap();
109            Args::List(n, verbose)
110        }
111
112        Some(("read", input)) => {
113            let n: usize = input.get_one::<String>("read").unwrap().parse().unwrap();
114            Args::Read(n)
115        }
116
117        Some(("edit", input)) => {
118            let n: usize = input.get_one::<String>("edit").unwrap().parse().unwrap();
119            Args::Edit(n)
120        }
121
122        Some(("delete", input)) => {
123            let n: usize = input.get_one::<String>("delete").unwrap().parse().unwrap();
124            Args::Delete(n, true)
125        }
126
127        Some(("search", input)) => {
128            let mut q = String::new();
129            let search_command = input.subcommand().unwrap_or(("search", input));
130            match search_command {
131                ("date", _sub_matches) => Args::DateFilter(q),
132                ("search", _sub_matches) => {
133                    q = input.get_one::<String>("search").unwrap().into();
134                    Args::Search(q)
135                }
136                (name, _) => {
137                    unreachable!("Unsupported subcommand `{name}`")
138                }
139            }
140        }
141
142        Some(("date search", input)) => {
143            let date = input.get_one::<String>("search").unwrap().into();
144            Args::DateSearch(date)
145        }
146
147        _ => unreachable!(),
148    }
149}