summaryrefslogblamecommitdiff
path: root/src/input.rs
blob: cdd39382e16a05edb23bbbc8930f79d17cd190ad (plain) (tree)
1
2
3
4
                                                                                                             
 
                                      
                  














                                          







                                      
       

 



                                      


                                      
                      

           
           

 

















































































                                                                                           


     








                                                                                   
          



























                                                                                                                     
          


                                                                                                               
          













                                                                                                                                                  
          


                                                                                                              
          



                                                                                                              
         

     
 











                                               

                 




















                                                                                        
 
























                                                                                 
 
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 download: bool,
    pub update: bool,
    pub mod_options: Option<ModOptions>,
    pub mod_id: Option<String>,
    pub mod_version: Option<String>,
    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 export: bool,
    pub import: bool,
    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,
}

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 download = false;
        let mut update = false;
        let mut mod_options: Option<ModOptions> = None;
        let mut mod_id: Option<String> = None;
        let mut mod_version: Option<String> = None;
        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 export = false;
        let mut import = false;
        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);
                    mod_id = Some(String::from(arg_split[1]));
                },
                "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]));
                }
                _ => return Err(MLError::new(ErrorType::ArgumentError, "UnknownArgument")),
            }
        }

        Ok(Self {
            command,
            download,
            update,
            mod_options,
            mod_id,
            mod_version,
            list,
            list_options,
            list_id,
            list_mcversion,
            modloader,
            directory,
            export,
            import,
            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),
    }
}

fn check_mod(mut input: Input, config: Cfg) -> MLE<Input> {
    print!("Checkmod");
    if input.mod_options.is_none() {
        return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ARGUMENT"));
    };
    match input.clone().mod_options.unwrap() {
        ModOptions::Add => {
            print!("Checkadd");
            if input.mod_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID")); };
            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() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID")); };
            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),
            download: false,
            update: false,
            mod_options: None,
            mod_id: None,
            mod_version: None,
            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,
            export: false,
            import: false,
            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),
            download: false,
            update: false,
            mod_options: Some(ModOptions::Add),
            mod_id: Some(String::from("test")),
            mod_version: None,
            list: Some(lists_get(config.clone(), String::from("one")).unwrap()),
            list_options: None,
            list_id: None,
            list_mcversion: None,
            modloader: None,
            directory: None,
            export: false,
            import: false,
            file: None
        }
    )
}