1use std::{collections::HashSet, io, path::PathBuf, str::FromStr};
2
3use clap::CommandFactory;
4use snafu::ResultExt;
5use strum::IntoEnumIterator;
6
7use crate::{
8 args::{
9 self, Args, BinaryCookiesArgs, ChromiumArgs, ChromiumName, FirefoxArgs, FirefoxName, Format,
10 },
11 binary_cookies::BinaryCookiesWriter,
12 chromium::ChromiumBased,
13 error::{self, Result},
14 firefox::FirefoxBased,
15};
16#[cfg(target_os = "macos")]
17use crate::{
18 args::{SafariArgs, Value},
19 safari::SafariBased,
20};
21
22pub async fn run_cli(args: crate::args::Args) -> Result<()> {
23 let output_dir = args.output_dir;
24
25 if args.all_browsers {
26 let chromium = tokio::spawn({
27 let output_dir = output_dir.clone();
28 let sep = args.sep.clone();
29 let host = args.host.clone();
30 async move {
31 ChromiumBased::multi_data(
32 ChromiumName::iter(),
33 output_dir,
34 sep,
35 host,
36 args.out_format,
37 )
38 .await
39 }
40 });
41
42 let firefox = tokio::spawn({
43 let host = args.host.clone();
44 let output_dir = output_dir.clone();
45 let sep = args.sep.clone();
46 async move {
47 FirefoxBased::multi_data(
48 FirefoxName::iter(),
49 output_dir,
50 sep,
51 host,
52 args.out_format,
53 )
54 .await
55 }
56 });
57
58 #[cfg(target_os = "macos")]
59 let safari = tokio::spawn({
60 let host = args.host.clone();
61 async move {
62 SafariBased::write_data(
63 HashSet::from_iter(Value::iter()),
64 None,
65 host,
66 args.sep,
67 output_dir,
68 args.out_format,
69 )
70 .await
71 }
72 });
73
74 #[cfg(not(target_os = "macos"))]
75 let (c, f) = tokio::join!(chromium, firefox);
76 #[cfg(target_os = "macos")]
77 let (c, f, s) = tokio::join!(chromium, firefox, safari);
78
79 c.context(error::TokioTaskSnafu)??;
80 f.context(error::TokioTaskSnafu)??;
81 #[cfg(target_os = "macos")]
82 if let Err(e) = s.context(error::TokioTaskSnafu)? {
83 tracing::error!("{e}");
85 }
86
87 return Ok(());
88 }
89
90 if let Some(core) = args.cmd {
91 match core {
92 args::SubCmd::Completions { shell } => {
93 shell.generate(&mut Args::command(), &mut io::stdout())
94 },
95 args::SubCmd::Chromium(ChromiumArgs { name, user_data_dir, values }) => {
96 ChromiumBased::write_data(
97 name,
98 user_data_dir,
99 args.host,
100 HashSet::from_iter(values.into_iter()),
101 output_dir,
102 args.sep,
103 args.out_format,
104 )
105 .await?;
106 },
107 args::SubCmd::Firefox(FirefoxArgs {
108 name,
109 base,
110 profile,
111 profile_path,
112 values,
113 }) => {
114 FirefoxBased::write_data(
115 name,
116 base,
117 profile,
118 profile_path,
119 args.host,
120 HashSet::from_iter(values.into_iter()),
121 output_dir,
122 args.sep,
123 args.out_format,
124 )
125 .await?
126 },
127 args::SubCmd::BinaryCookies(BinaryCookiesArgs { cookies_path, out_file }) => {
128 BinaryCookiesWriter::write_data(
129 cookies_path,
130 out_file.unwrap_or_else(|| match args.out_format {
131 Format::Csv => PathBuf::from_str(crate::BINARY_COOKIES_FILE_CSV).unwrap(),
132 Format::Json => PathBuf::from_str(crate::BINARY_COOKIES_FILE_JSON).unwrap(),
133 Format::JsonLines => {
134 PathBuf::from_str(crate::BINARY_COOKIES_FILE_JSONL).unwrap()
135 },
136 }),
137 args.sep,
138 args.out_format,
139 )?;
140 },
141 #[cfg(target_os = "macos")]
142 args::SubCmd::Safari(SafariArgs { values, cookies_path }) => {
143 SafariBased::write_data(
144 HashSet::from_iter(values.into_iter()),
145 cookies_path,
146 args.host,
147 args.sep,
148 output_dir,
149 args.out_format,
150 )
151 .await?
152 },
153 }
154 }
155
156 Ok(())
157}