lib/
entrypoint.rs

1use crate::cli::{Cli, Command};
2use crate::config;
3use crate::destinations::Destinations;
4use crate::errors::MusketError;
5use crate::shooters::{bluesky_shooter, linkedin_shooter, mastodon_shooter, turso_shooter};
6use clap::Parser;
7use tracing::{debug, level_filters::LevelFilter};
8use tracing_subscriber::EnvFilter;
9
10/// Runs the main logic of the application.
11///
12/// # Errors
13///
14/// This function will return an error if any of the commands fail.
15#[allow(clippy::too_many_lines)]
16pub async fn run() -> Result<Vec<String>, MusketError> {
17    let mut success_messages: Vec<String> = vec![];
18    let cli = Cli::parse();
19
20    tracing_subscriber::fmt()
21        .with_env_filter(
22            EnvFilter::builder()
23                .with_default_directive(LevelFilter::INFO.into())
24                .from_env_lossy(),
25        )
26        .without_time()
27        .init();
28
29    match cli.cmd {
30        Command::Init { force } => {
31            debug!("Inside run function. Command::Init");
32
33            let overwrite = force.unwrap_or(false);
34
35            if config::configuration_exists()? && !overwrite {
36                return Err(MusketError::Cli {
37                    message: "The configuration file already exists. If you want to overwrite it, please run the musket init command with the -f, --force option.".to_string(),
38                });
39            }
40
41            match config::configure() {
42                Ok(_) => {
43                    success_messages.push(format!("The configuration file has been created here: \"{}\". \nTo start using Musket, please complete the configuration file with your data.",
44                    config::get_configuration_path()
45                        .unwrap_or_default()
46                        .to_string_lossy()));
47                }
48                Err(e) => return Err(e.into()),
49            }
50        }
51        Command::Fire {
52            url,
53            destination,
54            tags,
55            commentary,
56            language,
57        } => {
58            debug!("Inside run function. Command::Fire");
59
60            if !config::configuration_exists()? {
61                return Err(MusketError::Cli {
62                    message: format!("The configuration file does not exist. If you want to send \"{url}\" to {} destination, please first run the musket init command and next fill the configuration file.", destination.unwrap_or_default().iter().map(std::string::ToString::to_string).collect::<Vec<String>>().join(", ")),
63                });
64            }
65
66            if destination.is_none() {
67                return Err(MusketError::Cli {
68                    message: format!("The url \"{url}\" cannot be sent to a non-existing destination. Set, at least, one valid destination."),
69                });
70            }
71
72            let cfg = config::configure()?;
73            let tags = tags.unwrap_or_default();
74            let destinations = destination.unwrap_or_default();
75
76            for target in destinations {
77                match target {
78                    Destinations::All => {
79                        success_messages.push(
80                            bluesky_shooter(
81                                &cfg,
82                                &url,
83                                tags.clone(),
84                                commentary.as_ref(),
85                                language.as_ref(),
86                            )
87                            .await?,
88                        );
89                        success_messages.push(
90                            linkedin_shooter(
91                                &cfg,
92                                &url,
93                                tags.clone(),
94                                commentary.as_ref(),
95                                language.as_ref(),
96                            )
97                            .await?,
98                        );
99                        success_messages.push(
100                            mastodon_shooter(
101                                &cfg,
102                                &url,
103                                tags.clone(),
104                                commentary.as_ref(),
105                                language.as_ref(),
106                            )
107                            .await?,
108                        );
109                        success_messages.push(turso_shooter(&cfg, &url, tags.clone(), None).await?);
110                    }
111                    Destinations::Bluesky => {
112                        success_messages.push(
113                            bluesky_shooter(
114                                &cfg,
115                                &url,
116                                tags.clone(),
117                                commentary.as_ref(),
118                                language.as_ref(),
119                            )
120                            .await?,
121                        );
122                    }
123                    Destinations::LinkedIn => {
124                        success_messages.push(
125                            linkedin_shooter(
126                                &cfg,
127                                &url,
128                                tags.clone(),
129                                commentary.as_ref(),
130                                language.as_ref(),
131                            )
132                            .await?,
133                        );
134                    }
135                    Destinations::Mastodon => {
136                        success_messages.push(
137                            mastodon_shooter(
138                                &cfg,
139                                &url,
140                                tags.clone(),
141                                commentary.as_ref(),
142                                language.as_ref(),
143                            )
144                            .await?,
145                        );
146                    }
147                    Destinations::Turso => {
148                        success_messages.push(turso_shooter(&cfg, &url, tags.clone(), None).await?);
149                    }
150                }
151            }
152        }
153    }
154    Ok(success_messages)
155}