1use anyhow::Result;
2use dialoguer::{theme::ColorfulTheme, Input};
3use colored::Colorize;
4
5use python::Python;
6use cmd::Cmd;
7use shell::Shell;
8use uri::Uri;
9use crate::db::StorageMode;
10use crate::suggest;
11
12use crate::db;
13
14pub mod python;
15pub mod cmd;
16pub mod shell;
17pub mod uri;
18
19pub trait QaliCommand {
20 fn execute(&self, args: Option<&String>) -> Result<()>;
21 fn new(command: &String) -> Result<Self> where Self: Sized;
22 fn is_valid(command: &String) -> bool where Self: Sized;
23 fn export(&self) -> Result<String>;
24}
25
26pub fn parse_command(command: &String) -> Result<Box<dyn QaliCommand>> {
27 if Python::is_valid(command) {
28 Ok(Box::new(Python::new(command)?))
29 } else if Shell::is_valid(command) {
30 Ok(Box::new(Shell::new(command)?))
31 } else if Uri::is_valid(command) {
32 Ok(Box::new(Uri::new(command)?))
33 } else if Cmd::is_valid(command) {
34 Ok(Box::new(Cmd::new(command)?))
35 } else {
36 Err(anyhow::anyhow!("Command {} is not valid", command))
37 }
38}
39
40pub fn save_alias(alias: &String, command: &String, m:&StorageMode) -> Result<()> {
41 let action = parse_command(command)?;
42 let store = action.export()?;
43 db::save(alias, &store, m)
44}
45
46pub fn suggest_save_alias(command: &String, m:&StorageMode) -> Result<()>{
47 let alias: String = {
48 let suggestion = suggest::suggest_alias(command);
49 match suggestion{
50 Ok(s) => {
51 println!("{}", "Suggestion found".blue());
52 Input::with_theme(&ColorfulTheme::default())
53 .with_prompt("Enter alias:")
54 .default(s)
55 .interact()?
56 },
57 Err(_) => {
58 Input::with_theme(&ColorfulTheme::default())
59 .with_prompt("Enter alias:")
60 .interact()?
61 }
62 }
63 };
64 let action = parse_command(command)?;
65 let store = action.export()?;
66 db::save(&alias, &store, m)
67}
68
69pub fn execute_alias(alias: &String, args: Option<&String>) -> Result<()> {
70 let command = db::read_all(alias)?;
71 let cmd = parse_command(&command)?;
72 cmd.execute(args)
73}
74
75pub fn select_and_execute_alias() -> Result<()> {
76 let alias = db::interface::select()?;
77 let args = {
78 let inp: String = Input::with_theme(&ColorfulTheme::default())
79 .with_prompt("Enter arguments(if any)")
80 .allow_empty(true)
81 .interact_text()?;
82 if inp.is_empty() {
83 None
84 } else {
85 Some(inp)
86 }
87 };
88 execute_alias(&alias, args.as_ref())
89}