xtagger/
args.rs

1use std::path::PathBuf;
2
3use clap::{ArgAction, ArgGroup, Args, Parser};
4use xtag::XTags;
5
6// FIXME print help if no args
7#[derive(Parser)]
8#[command(author, version, about, long_about = None)]
9// #[command(group(ArgGroup::new("any").multiple(true).required(true).
10//     args(&["add", "remove", "find", "replace", "copy", "delete", "find", "replace", "filter", "bookmark"])))]
11#[command(group(ArgGroup::new("printing").multiple(false).required(false).
12    args(&["list", "show", "tags"])))]
13#[command(group(ArgGroup::new("manipulating").multiple(true).required(false).
14    args(&["add", "remove", "copy", "find", "replace"])))]
15#[command(group(ArgGroup::new("deleting").multiple(false).required(false).
16    args(&["delete"]).
17    conflicts_with("manipulating").
18    conflicts_with("renaming")))]
19#[command(group(ArgGroup::new("renaming").multiple(true).required(false).
20    args(&["find", "replace"]).
21    requires_all(&["find", "replace"])))]
22#[command(group(ArgGroup::new("filtering").multiple(false).required(false).
23    args(&["filter", "bookmark"])))]
24#[command(disable_help_flag = true)]
25pub struct Arguments {
26    // Use only long version of help, because short clashes with hyperlink.
27    // Don't know why Option is needed to make argument optional in this case.
28    /// Print help information
29    #[arg(long, action = ArgAction::Help)]
30    help: Option<bool>,
31
32    /// Print files as hyperlinks
33    #[arg(short, long)]
34    pub hyperlink: bool,
35
36    /// Don't change anything
37    #[arg(short, long)]
38    pub dry_run: bool,
39
40    #[command(flatten)]
41    pub print: Print,
42
43    #[command(flatten)]
44    pub manipulate: Manipulate,
45
46    #[command(flatten)]
47    pub filter: Filter,
48
49    // Args
50    #[arg(value_name = "GLOB", value_hint = clap::ValueHint::DirPath)]
51    pub globs: Vec<PathBuf>,
52}
53
54#[derive(Args)]
55pub struct Manipulate {
56    /// Add tags
57    #[arg(short, long, value_name = "TAGS", value_parser = xtag::csl_to_map)]
58    pub add: Option<XTags>,
59
60    /// Remove tags
61    #[arg(short, long, value_name = "TAGS", value_parser = xtag::csl_to_map)]
62    pub remove: Option<XTags>,
63
64    /// Delete tags
65    #[arg(long)]
66    pub delete: bool,
67
68    /// Copy tags
69    #[arg(long)]
70    pub copy: bool,
71
72    #[command(flatten)]
73    pub rename: Rename,
74}
75
76#[derive(Args)]
77pub struct Filter {
78    /// filter per search term
79    #[arg(short, long, value_name = "TERM")]
80    pub filter: Option<String>,
81
82    /// filter per bookmark
83    #[arg(short, long, value_name = "PATH", value_hint = clap::ValueHint::DirPath)]
84    pub bookmark: Option<PathBuf>,
85}
86
87#[derive(Args)]
88pub struct Rename {
89    #[arg(long, value_name = "REGEX")]
90    pub find: Option<String>,
91
92    #[arg(long, value_name = "REGEX")]
93    pub replace: Option<String>,
94}
95
96#[derive(Args)]
97pub struct Print {
98    /// List files
99    #[arg(short, long)]
100    pub list: bool,
101
102    /// List files with tags and values
103    #[arg(short, long)]
104    pub show: bool,
105
106    /// List all used tags
107    #[arg(short, long)]
108    pub tags: bool,
109}