1use std::path::PathBuf;
2
3use clap::{
4 builder::{IntoResettable, OsStr, Resettable},
5 ArgAction, ValueHint,
6};
7
8#[derive(Clone)]
9#[derive(Debug)]
10#[derive(clap::Parser)]
11pub struct Args {
12 #[command(subcommand)]
13 pub cmd: Option<SubCmd>,
14
15 #[arg(
16 short,
17 long,
18 default_value("results"),
19 verbatim_doc_comment,
20 value_hint(ValueHint::DirPath)
21 )]
22 pub output_dir: PathBuf,
25
26 #[arg(short, long)]
27 pub all_browsers: bool,
29
30 #[arg(long, default_value(","), value_hint(ValueHint::Other))]
31 pub sep: String,
33
34 #[arg(long, id("domain"), value_hint(ValueHint::Url))]
35 pub host: Option<String>,
37
38 #[arg(long, default_value(Format::Csv))]
39 pub out_format: Format,
41}
42
43#[derive(Clone, Copy)]
44#[derive(Debug)]
45#[derive(Default)]
46pub enum Format {
47 #[default]
48 Csv,
49 Json,
50 JsonLines,
51}
52
53impl clap::ValueEnum for Format {
54 fn value_variants<'a>() -> &'a [Self] {
55 &[Self::Csv, Self::Json, Self::JsonLines]
56 }
57 fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::builder::PossibleValue> {
58 match self {
59 Self::Csv => Some(clap::builder::PossibleValue::new("csv")),
60 Self::Json => Some(clap::builder::PossibleValue::new("json")),
61 Self::JsonLines => Some(clap::builder::PossibleValue::new("jsonl")),
62 }
63 }
64}
65
66impl IntoResettable<OsStr> for Format {
67 fn into_resettable(self) -> clap::builder::Resettable<OsStr> {
68 Resettable::Value(match self {
69 Format::Csv => "csv".into(),
70 Format::Json => "json".into(),
71 Format::JsonLines => "jsonl".into(),
72 })
73 }
74}
75
76#[derive(Clone)]
77#[derive(Debug)]
78#[derive(clap::Subcommand)]
79pub enum SubCmd {
80 Chromium(ChromiumArgs),
82 Firefox(FirefoxArgs),
84 BinaryCookies(BinaryCookiesArgs),
86 #[cfg(target_os = "macos")]
87 Safari(SafariArgs),
89 Completions {
91 shell: clap_complete_command::Shell,
92 },
93}
94
95#[derive(Clone, Copy)]
96#[derive(Debug)]
97#[derive(Default)]
98#[derive(PartialEq, Eq, PartialOrd, Ord)]
99#[derive(clap::ValueEnum)]
100#[derive(Hash)]
101#[derive(strum::EnumIter)]
102pub enum Value {
103 #[default]
104 Cookie,
105 Login,
106}
107
108#[derive(Clone)]
109#[derive(Debug)]
110#[derive(PartialEq, Eq, PartialOrd, Ord)]
111#[derive(clap::Args)]
112pub struct SafariArgs {
113 #[arg(short, long, value_delimiter(','), action(ArgAction::Append))]
114 pub values: Vec<Value>,
116
117 #[arg(long, value_hint(ValueHint::FilePath))]
118 pub cookies_path: Option<PathBuf>,
119}
120
121#[derive(Clone)]
122#[derive(Debug)]
123#[derive(PartialEq, Eq, PartialOrd, Ord)]
124#[derive(clap::Args)]
125pub struct ChromiumArgs {
126 #[arg(short, long)]
127 pub name: ChromiumName,
128
129 #[arg(long, id("DIR"), verbatim_doc_comment, value_hint(ValueHint::DirPath))]
130 #[cfg_attr(target_os = "linux", doc = "[example value: ~/.config/google-chrome]")]
132 #[cfg_attr(
133 target_os = "macos",
134 doc = "[example value: ~/Library/Application Support/Google/Chrome]"
135 )]
136 #[cfg_attr(
137 target_os = "windows",
138 doc = r"[example value: ~\AppData\Local\Google\Chrome\User Data]"
139 )]
140 pub user_data_dir: Option<PathBuf>,
141
142 #[arg(short, long, value_delimiter(','), action(ArgAction::Append))]
143 pub values: Vec<Value>,
144}
145
146#[derive(Clone, Copy)]
147#[derive(Debug)]
148#[derive(PartialEq, Eq, PartialOrd, Ord)]
149#[derive(clap::ValueEnum)]
150#[clap(rename_all = "PascalCase")]
151#[derive(strum::EnumIter)]
152pub enum ChromiumName {
153 Chrome,
154 Edge,
155 Chromium,
156 Brave,
157 Vivaldi,
158 Yandex,
159 Opera,
160 #[cfg(not(target_os = "linux"))]
161 Arc,
162 #[cfg(not(target_os = "linux"))]
163 OperaGX,
164 #[cfg(not(target_os = "linux"))]
165 CocCoc,
166}
167
168#[derive(Clone)]
169#[derive(Debug)]
170#[derive(PartialEq, Eq, PartialOrd, Ord)]
171#[derive(clap::Args)]
172pub struct FirefoxArgs {
173 #[arg(short, long)]
174 pub name: FirefoxName,
175
176 #[arg(long, id("DIR"), value_hint(ValueHint::DirPath))]
177 #[cfg_attr(target_os = "linux", doc = "[example value: ~/.mozilla/firefox]")]
179 #[cfg_attr(
180 target_os = "macos",
181 doc = "[example value: ~/Library/Application Support/Firefox]"
182 )]
183 #[cfg_attr(
184 target_os = "windows",
185 doc = r"[example value: ~\AppData\Roaming\Mozilla\Firefox]"
186 )]
187 pub base: Option<PathBuf>,
188
189 #[arg(short('P'), id("profile"), value_hint(ValueHint::Other))]
190 pub profile: Option<String>,
192
193 #[arg(long("profile"), id("path"))]
194 #[arg(verbatim_doc_comment)]
195 pub profile_path: Option<PathBuf>,
198
199 #[arg(short, long, value_delimiter(','), action(ArgAction::Append))]
200 pub values: Vec<Value>,
202}
203
204#[derive(Clone, Copy)]
205#[derive(Debug)]
206#[derive(PartialEq, Eq, PartialOrd, Ord)]
207#[derive(clap::ValueEnum)]
208#[clap(rename_all = "PascalCase")]
209#[derive(strum::EnumIter)]
210pub enum FirefoxName {
211 Firefox,
212 Librewolf,
213 Floorp,
214}
215
216#[derive(Clone)]
217#[derive(Debug)]
218#[derive(PartialEq, Eq, PartialOrd, Ord)]
219#[derive(clap::Args)]
220pub struct BinaryCookiesArgs {
221 #[arg(short('i'), long, value_hint(ValueHint::FilePath))]
222 pub cookies_path: PathBuf,
223 #[arg(short, long, value_hint(ValueHint::FilePath))]
224 pub out_file: Option<PathBuf>,
225}