vendor 0.2.0

Easy to use package manager library
Documentation
use crate::{helpers, MESSAGES};
use colored::Colorize;
use global_placeholders::global;
use indicatif::{ProgressBar, ProgressStyle};
use inquire::{min_length, Password, PasswordDisplayMode, Text};
use std::io::Write;

#[derive(Debug, serde::Deserialize)]
struct Record {
    id: String,
}

#[derive(Debug, serde::Deserialize)]
struct Response {
    token: String,
    record: Record,
}

pub fn login() {
    let name = global!("vendor.name");
    let registry_link = global!("vendor.registry");

    match home::home_dir() {
        Some(path) => {
            if !helpers::Exists::folder(format!("{}/.{name}", path.display())).unwrap() {
                std::fs::create_dir_all(format!("{}/.{name}", path.display())).unwrap();
                println!("created {}/.{name}", &path.display());
            }

            if !helpers::Exists::folder(format!("{}/.{name}/credentials", path.display())).unwrap() {
                std::fs::create_dir_all(format!("{}/.{name}/credentials", path.display())).unwrap();
                println!("created {}/.{name}/credentials", &path.display());
            }

            println!("{}{registry_link}", MESSAGES.get("registry_login").unwrap());

            let identity_string: String;
            let password_string: String;
            let client = reqwest::blocking::Client::new();
            let identity = Text::new("identity:").prompt();
            let password = Password::new("password:")
                .with_display_toggle_enabled()
                .with_display_mode(PasswordDisplayMode::Masked)
                .with_validator(min_length!(8))
                .without_confirmation()
                .prompt();

            match identity {
                Ok(value) => identity_string = value.clone(),
                Err(_) => std::process::exit(1),
            };

            match password {
                Ok(value) => password_string = value.clone(),
                Err(_) => std::process::exit(1),
            };

            let pb = ProgressBar::new_spinner();
            pb.enable_steady_tick(std::time::Duration::from_millis(80));
            pb.set_style(ProgressStyle::with_template("{spinner:.yellow} {msg}").unwrap().tick_strings(&[
                "[    ]", "[=   ]", "[==  ]", "[=== ]", "[ ===]", "[  ==]", "[   =]", "[    ]", "[   =]", "[  ==]", "[ ===]", "[====]", "[=== ]", "[==  ]", "[=   ]", "",
            ]));
            pb.set_message("logging in...");

            let response = client
                .post(format!("{registry_link}/api/collections/just_auth_system/auth-with-password"))
                .body(format!("{{\"identity\":\"{identity_string}\",\"password\":\"{password_string}\"}}"))
                .header(reqwest::header::CONTENT_TYPE, reqwest::header::HeaderValue::from_static("application/json"))
                .send();

            match response {
                Ok(response) => {
                    match serde_json::from_str::<Response>(&response.text().unwrap()) {
                        Ok(json) => {
                            let mut file = std::fs::File::create(format!("{}/.{name}/credentials/{}].json", path.display(), registry_link.replace("://", "["))).unwrap();
                            file.write_all(format!("{{\"token\":\"{}\",\"access\":\"{}\"}}", json.token, json.record.id).as_bytes()).unwrap();
                            pb.finish_with_message(format!(
                                "\x08{} {} {}",
                                "".green(),
                                MESSAGES.get("login_msg").unwrap().bright_green(),
                                format!("({})", json.record.id).white()
                            ));
                        }
                        Err(_) => {
                            eprint!("\r{} {}\n", "".red(), MESSAGES.get("login_error").unwrap().bright_red());
                            std::process::exit(1);
                        }
                    };
                }
                Err(err) => eprint!("\r{} {}\n", "".red(), format!("{}{}", MESSAGES.get("login_error_generic").unwrap(), err.to_string()).bright_red()),
            };
        }
        None => {
            eprintln!("{}", MESSAGES.get("home_error").unwrap().red());
            std::process::exit(1);
        }
    }
}

pub fn logout() {
    let name = global!("vendor.name");

    match home::home_dir() {
        Some(path) => {
            if let Err(_) = std::fs::remove_file(format!("{}/.{name}/credentials.json", path.display())) {
                eprintln!("{}", MESSAGES.get("logout_error").unwrap().red());
            } else {
                println!("{}", MESSAGES.get("logout_msg").unwrap().green())
            }
        }
        None => {
            eprintln!("{}", MESSAGES.get("home_error").unwrap().red());
            std::process::exit(1);
        }
    }
}