rocal_cli/
runner.rs

1use clap::{builder::Str, command, Arg, Command, Id};
2
3use crate::commands::{
4    build::build, init::init, login::login, migrate, password, publish::publish,
5    register::register, subscribe::subscribe, sync_servers, unsubscribe::unsubscribe,
6};
7
8pub async fn run() {
9    let matches = command!()
10        .subcommand(
11            Command::new(Subcommand::Register)
12                .about("Create a new account in Rocal platform")
13        )
14        .subcommand(
15            Command::new(Subcommand::Login)
16                .about("Login to Rocal platform")
17        )
18        .subcommand(
19            Command::new(Subcommand::Subscribe)
20                .about("Subscribe Rocal platform to publish a Rocal app")
21        )
22        .subcommand(
23            Command::new(Subcommand::Unsubscribe)
24                .about("Unsubscribe Rocal platform which leads to revoke tokens and shut your hosting app down")
25        )
26        .subcommand(
27            Command::new(Subcommand::New)
28                .about("Create a new Rocal app")
29                .arg(
30                    Arg::new(InitCommandArg::Name)
31                        .short('n')
32                        .long("name")
33                        .required(true)
34                        .help("Set the resulting package name"),
35                ),
36        )
37        .subcommand(Command::new(Subcommand::Build).about("Build a Rocal app"))
38        .subcommand(
39            Command::new(Subcommand::Run)
40                .about("Run a Rocal app on your local")
41                .arg(
42                    Arg::new(RunCommandArg::Port)
43                        .short('p')
44                        .long("port")
45                        .required(false)
46                        .help("Set port where you want to serve an app")
47                )
48        )
49        .subcommand(Command::new(Subcommand::Publish).about("Publish a Rocal app"))
50        .subcommand(
51            Command::new(Subcommand::Password)
52                .about("Password settings")
53                .arg_required_else_help(true)
54                .subcommand(Command::new(PasswordSubcommand::Reset).about("Reset your password"))
55        )
56        .subcommand(
57            Command::new(Subcommand::SyncServers)
58                .about("Manage sync servers")
59                .arg_required_else_help(true)
60                .subcommand(Command::new(SyncServersSubcommand::List).about("List available sync servers and show app_id"))
61        )
62        .subcommand(
63            Command::new(Subcommand::Migrate)
64                .about("Manage migrations")
65                .arg_required_else_help(true)
66                .subcommand(
67                    Command::new(MigrateSubcommand::Add)
68                        .about("Add a new migration file. e.g. db/migrations/<timestamp>-<name>.sql")
69                        .arg(Arg::new("name").required(true))
70                )
71        )
72        .about("A tool to create and build a Rocal app.")
73        .arg_required_else_help(true)
74        .get_matches();
75
76    match matches.subcommand() {
77        Some((name, arg_matches)) => {
78            if name == Subcommand::New.as_str() {
79                if let Some(name) = arg_matches.get_one::<String>(InitCommandArg::Name.as_str()) {
80                    init(name);
81                }
82            } else if name == Subcommand::Build.as_str() {
83                build();
84            } else if name == Subcommand::Publish.as_str() {
85                publish().await;
86            } else if name == Subcommand::Register.as_str() {
87                register().await;
88            } else if name == Subcommand::Login.as_str() {
89                login().await;
90            } else if name == Subcommand::Password.as_str() {
91                match arg_matches.subcommand() {
92                    Some((name, _arg_matches)) => {
93                        if name == PasswordSubcommand::Reset.as_str() {
94                            password::reset().await;
95                        }
96                    }
97                    None => (),
98                }
99            } else if name == Subcommand::Subscribe.as_str() {
100                if let Err(err) = subscribe().await {
101                    println!("Error: {}", err.to_string());
102                }
103            } else if name == Subcommand::Unsubscribe.as_str() {
104                unsubscribe().await;
105            } else if name == Subcommand::Migrate.as_str() {
106                match arg_matches.subcommand() {
107                    Some((name, arg_matches)) => {
108                        if name == MigrateSubcommand::Add.as_str() {
109                            let name = arg_matches
110                                .get_one::<String>("name")
111                                .expect("required argument");
112                            migrate::add(&name);
113                        }
114                    }
115                    None => (),
116                }
117            } else if name == Subcommand::SyncServers.as_str() {
118                match arg_matches.subcommand() {
119                    Some((name, _arg_matches)) => {
120                        if name == SyncServersSubcommand::List.as_str() {
121                            sync_servers::list().await;
122                        }
123                    }
124                    None => (),
125                }
126            } else if name == Subcommand::Run.as_str() {
127                build();
128                if let Some(port) = arg_matches.get_one::<String>(RunCommandArg::Port.as_str()) {
129                    rocal_dev_server::run(Some(&port));
130                } else {
131                    rocal_dev_server::run(None);
132                }
133            }
134        }
135        None => (),
136    }
137}
138
139enum Subcommand {
140    Register,
141    Login,
142    Subscribe,
143    Unsubscribe,
144    New,
145    Build,
146    Publish,
147    Password,
148    SyncServers,
149    Run,
150    Migrate,
151}
152
153enum PasswordSubcommand {
154    Reset,
155}
156
157enum InitCommandArg {
158    Name,
159}
160
161enum SyncServersSubcommand {
162    List,
163}
164
165enum RunCommandArg {
166    Port,
167}
168
169enum MigrateSubcommand {
170    Add,
171}
172
173impl Into<Str> for Subcommand {
174    fn into(self) -> Str {
175        self.as_str().into()
176    }
177}
178
179impl Subcommand {
180    pub fn as_str(self) -> &'static str {
181        match self {
182            Subcommand::Register => "register",
183            Subcommand::Login => "login",
184            Subcommand::Subscribe => "subscribe",
185            Subcommand::Unsubscribe => "unsubscribe",
186            Subcommand::New => "new",
187            Subcommand::Build => "build",
188            Subcommand::Publish => "publish",
189            Subcommand::Password => "password",
190            Subcommand::SyncServers => "sync-servers",
191            Subcommand::Run => "run",
192            Subcommand::Migrate => "migrate",
193        }
194    }
195}
196
197impl Into<Id> for InitCommandArg {
198    fn into(self) -> Id {
199        self.as_str().into()
200    }
201}
202
203impl InitCommandArg {
204    pub fn as_str(self) -> &'static str {
205        match self {
206            InitCommandArg::Name => "name",
207        }
208    }
209}
210
211impl Into<Str> for PasswordSubcommand {
212    fn into(self) -> Str {
213        self.as_str().into()
214    }
215}
216
217impl PasswordSubcommand {
218    pub fn as_str(self) -> &'static str {
219        match self {
220            PasswordSubcommand::Reset => "reset",
221        }
222    }
223}
224
225impl Into<Str> for SyncServersSubcommand {
226    fn into(self) -> Str {
227        self.as_str().into()
228    }
229}
230
231impl SyncServersSubcommand {
232    pub fn as_str(self) -> &'static str {
233        match self {
234            SyncServersSubcommand::List => "ls",
235        }
236    }
237}
238
239impl Into<Str> for MigrateSubcommand {
240    fn into(self) -> Str {
241        self.as_str().into()
242    }
243}
244
245impl MigrateSubcommand {
246    pub fn as_str(self) -> &'static str {
247        match self {
248            MigrateSubcommand::Add => "add",
249        }
250    }
251}
252
253impl Into<Id> for RunCommandArg {
254    fn into(self) -> Id {
255        self.as_str().into()
256    }
257}
258
259impl RunCommandArg {
260    pub fn as_str(self) -> &'static str {
261        match self {
262            RunCommandArg::Port => "port",
263        }
264    }
265}