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