summaryrefslogblamecommitdiff
path: root/src/input.rs
blob: 4e59c5077c12603e3ecb225403afca0b2d90e930 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                                             
 
                                      
                  
                             


                                        
                          





                                          
                                      
                             







                                      
       

 



                                      


                                      
                      

           
           

 





                                      









                                                                    


                                                       
                                    





                                                         
                                                     










                                                                       
                  


                                                        

















                                                                       




















                                                                                        

















                                                                     





                                                                                           


                        
                        





                           
                       

                


     








                                                                                   
          
















                                                                                
                                                        
                                                           



                                                                              
                                           
                            
                                                                                                                                                         

                                                                                                                     
          
                               
                                                                                                                                                         
                     
          













                                                                                                                                                  
          


                                                                                                              
          



                                                                                                              
         

     
 











                                               

                 




                                                                                        


                              
                               





                                                         
                             


                      
 








                                                                                 


                                               
                               





                                                                                
                             


                      
 
use crate::{error::{MLE, MLError, ErrorType}, Modloader, config::Cfg, db::lists_get, get_current_list, List};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Input {
    pub command: Option<Cmd>,
    pub mod_options: Option<ModOptions>,
    pub mod_id: Option<String>,
    pub mod_version: Option<String>,
    pub set_version: bool,
    pub list: Option<List>,
    pub list_options: Option<ListOptions>,
    pub list_id: Option<String>,
    pub list_mcversion: Option<String>,
    pub modloader: Option<Modloader>,
    pub directory: Option<String>,
    pub io_options: Option<IoOptions>,
    pub file: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Cmd {
    Mod,
    List,
    Update,
    Download,
    Io,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ModOptions {
    Add,
    Remove
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ListOptions {
    Add,
    Remove,
    Change,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IoOptions {
    Export,
    Import
}

impl Input {
    fn from(config: Cfg, input: Vec<String>) -> MLE<Self> {
        let input_string = input.join(" ");
        let mut args: Vec<&str> = input_string.split('-').collect();
        args.reverse();
        args.pop();
        args.reverse();
        
        let mut command: Option<Cmd> = None;

        let mut mod_options: Option<ModOptions> = None;
        let mut mod_id: Option<String> = None;
        let mut mod_version: Option<String> = None;
        let mut set_version = false;
        let mut list: Option<List> = None;
        let mut list_options: Option<ListOptions> = None;
        let mut list_id: Option<String> = None;
        let mut list_mcversion: Option<String> = None;
        let mut modloader: Option<Modloader> = None;
        let mut directory: Option<String> = None;
        let mut io_options: Option<IoOptions> = None;
        let mut file: Option<String> = None;
        
        for arg in args {
            let arg_split: Vec<&str> = arg.trim().split(" ").collect();
            match arg_split[0] {
                "v" | "version" => { show_version(); },
                "d" | "download" => {
                    command = Some(Cmd::Download);
                },
                "u" | "update" => {
                    command = Some(Cmd::Update);
                },
                "ma" => {
                    command = Some(Cmd::Mod);
                    mod_options = Some(ModOptions::Add);
                    if arg_split.len() != 1 {
                        mod_id = Some(String::from(arg_split[1]));
                    }
                },
                "mr" => {
                    command = Some(Cmd::Mod);
                    mod_options = Some(ModOptions::Remove);
                    if arg_split.len() != 1 {
                        mod_id = Some(String::from(arg_split[1]));
                    }
                },
                "mv" => {
                    if arg_split.len() != 1 {
                        mod_version = Some(String::from(arg_split[1]));
                    };
                },
                "set-version" => {
                    set_version = true;
                },
                "l" => {
                    list = Some(lists_get(config.clone(), String::from(arg_split[1]))?);
                }
                "la" => {
                    command = Some(Cmd::List);
                    list_options = Some(ListOptions::Add);
                    list_id = Some(String::from(arg_split[1]));
                },
                "lr" => {
                    command = Some(Cmd::List);
                    list_options = Some(ListOptions::Remove);
                    list_id = Some(String::from(arg_split[1]));
                },
                "lc" => {
                    command = Some(Cmd::List);
                    list_options = Some(ListOptions::Change);
                    list_id = Some(String::from(arg_split[1]));
                },
                "lv" => {
                    list_mcversion = Some(String::from(arg_split[1]));
                },
                "ml" => {
                    modloader = Some(Modloader::from(arg_split[1])?);
                },
                "dir" => {
                    directory = Some(String::from(arg_split[1]));
                },
                "export" => {
                    command = Some(Cmd::Io);
                    io_options = Some(IoOptions::Export);
                },
                "import" => {
                    command = Some(Cmd::Io);
                    io_options = Some(IoOptions::Import);
                },
                "f" => {
                    file = Some(String::from(arg_split[1]));
                },
                _ => return Err(MLError::new(ErrorType::ArgumentError, "UnknownArgument")),
            }
        }

        Ok(Self {
            command,
            mod_options,
            mod_id,
            mod_version,
            set_version,
            list,
            list_options,
            list_id,
            list_mcversion,
            modloader,
            directory,
            io_options,
            file
        })
    }
}

fn show_version() {
    match std::env::var("DEV") {
        Ok(dev) => {
            let devint = dev.parse::<i32>().unwrap();
            if devint >= 1 {
                println!("Modlist by FxQnLr v{} (DEV)", env!("CARGO_PKG_VERSION"));
            } else {
                println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION"));
            }
        },
        Err(..) => println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION")),
    }
    std::process::exit(0);
}

pub async fn get_input(config: Cfg, args: Vec<String>) -> MLE<Input> {
    let input = Input::from(config.clone(), args)?;

    match input.clone().command.unwrap() {
        Cmd::Mod => check_mod(input, config),
        Cmd::List => check_list(input),
        Cmd::Update => check_update(input),
        Cmd::Download => check_download(input),
        Cmd::Io => check_io(input),
    }
}

//Move checks to commands? translate to variables there?
fn check_mod(mut input: Input, config: Cfg) -> MLE<Input> {
    if input.mod_options.is_none() {
        return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ARGUMENT"));
    };
    match input.clone().mod_options.unwrap() {
        //Check for MV if no mod-id on both
        ModOptions::Add => {
            if input.mod_id.is_none() && input.mod_version.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID_MODVERSION")); };
            if input.list_id.is_none() { println!("NOLIST"); input.list = Some(get_current_list(config.clone())?); };
            Ok(input)
        },
        ModOptions::Remove => {
            if input.mod_id.is_none() && input.mod_version.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID_MODVERSION")); };
            Ok(input)
        },
    }
}

fn check_list(mut input: Input) -> MLE<Input> {
    if input.list_options.is_none() {
        return Err(MLError::new(ErrorType::ArgumentError, "NO_LIST_ARGUMENT"));
    };
    match input.clone().list_options.unwrap() {
        ListOptions::Add => {
            if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_ID")); };
            if input.list_mcversion.is_none() { /*TODO Get latest version */ input.list_mcversion = Some(String::from("1.19.3")) };
            if input.modloader.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_MODLOADER")); };
            if input.directory.is_none() { input.directory = Some(format!("./downloads/{}", input.clone().list_id.expect("earlier if failed"))) };
            Ok(input)
        },
        ListOptions::Remove => {
            if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_ID")); };
            Ok(input)
        },
        ListOptions::Change => {
            //TODO check if no change
            if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_ID")); };
            Ok(input)
        }
    }
}

fn check_update(input: Input) -> MLE<Input> {
    Ok(input)
}

fn check_download(input: Input) -> MLE<Input> {
    Ok(input)
}

fn check_io(input: Input) -> MLE<Input> {
    Ok(input)
}

#[test]
fn input_from() {
    let config = Cfg::init("modlist.toml").unwrap();
    assert_eq!(
        Input::from(config.clone(), vec![String::from("-la test -lv 1.19.3")]).unwrap(),
        Input {
            command: Some(Cmd::List),
            mod_options: None,
            mod_id: None,
            mod_version: None,
            set_version: false,
            list: None,
            list_options: Some(ListOptions::Add),
            list_id: Some(String::from("test")),
            list_mcversion: Some(String::from("1.19.3")),
            modloader: None,
            directory: None,
            io_options: None,
            file: None
        }
    );

}

#[tokio::test]
async fn get_input_test() {
    let config = Cfg::init("modlist.toml").unwrap();
    assert_eq!(
        get_input(config.clone(), vec![String::from("-ma test")]).await.unwrap(),
        Input {
            command: Some(Cmd::Mod),
            mod_options: Some(ModOptions::Add),
            mod_id: Some(String::from("test")),
            mod_version: None,
            set_version: false,
            list: Some(lists_get(config.clone(), String::from("one")).unwrap()),
            list_options: None,
            list_id: None,
            list_mcversion: None,
            modloader: None,
            directory: None,
            io_options: None,
            file: None
        }
    )
}