cleaned up flags

This commit is contained in:
Vomitblood 2024-04-21 17:43:18 +08:00
parent 9156ff8709
commit 68ad9c816b
9 changed files with 291 additions and 164 deletions

155
Cargo.lock generated
View file

@ -34,54 +34,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1"
[[package]]
name = "anstream"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]]
name = "anstyle-parse"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "anyhow"
version = "1.0.82"
@ -111,6 +63,17 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.2.0"
@ -301,30 +264,28 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.4"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
dependencies = [
"anstream",
"anstyle",
"atty",
"bitflags 1.3.2",
"clap_lex",
"indexmap 1.9.3",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.7.0"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "color_quant"
@ -332,12 +293,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@ -703,7 +658,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap",
"indexmap 2.2.6",
"slab",
"tokio",
"tokio-util",
@ -720,6 +675,12 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.3"
@ -732,6 +693,15 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "hmac"
version = "0.12.1"
@ -861,6 +831,16 @@ version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126"
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
]
[[package]]
name = "indexmap"
version = "2.2.6"
@ -868,7 +848,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
dependencies = [
"equivalent",
"hashbrown",
"hashbrown 0.14.3",
]
[[package]]
@ -1231,6 +1211,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "os_str_bytes"
version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -1841,9 +1827,9 @@ dependencies = [
[[package]]
name = "strsim"
version = "0.11.1"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "subtle"
@ -1920,6 +1906,21 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
[[package]]
name = "thiserror"
version = "1.0.58"
@ -2051,7 +2052,7 @@ version = "0.22.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
dependencies = [
"indexmap",
"indexmap 2.2.6",
"serde",
"serde_spanned",
"toml_datetime",
@ -2127,12 +2128,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "v_frame"
version = "0.3.8"

View file

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
clap = { version = "4.5.4", features = ["cargo"] }
clap = { version = "3.2.22", features = ["cargo"] }
crossterm = "0.27.0"
ctrlc = "3.4.4"
dirs = "5.0.1"

View file

@ -82,11 +82,10 @@ pub fn fetch(extract_destination: &std::path::Path, verbose: bool) {
};
// cleanup
// TODO: uncomment
// match cleanup() {
// Ok(_) => (),
// Err(e) => eprintln!("Error cleaning up: {}", e),
// };
match cleanup() {
Ok(_) => (),
Err(e) => eprintln!("Error cleaning up: {}", e),
};
}
fn create_working_directory() -> std::io::Result<()> {
@ -159,42 +158,6 @@ fn fetch_pokemon_json() -> Result<(), Box<dyn std::error::Error>> {
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct Slug {
eng: String,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct Forms {
// ignoring actual details in the forms and just capturing form names
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct Generation {
forms: std::collections::HashMap<String, Forms>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct Pokemon {
idx: String,
slug: Slug,
#[serde(rename = "gen-8")]
gen_8: Generation,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct PokemonCollection {
#[serde(flatten)]
entries: std::collections::HashMap<String, Pokemon>,
}
#[derive(serde::Serialize, Debug)]
struct ProcessedPokemon {
pokedex: String,
name: String,
forms: Vec<String>,
}
fn process_pokemon_json(
output_directory_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
@ -222,7 +185,7 @@ fn process_pokemon_json(
fn read_pokemon_file(
file_path: &std::path::Path,
) -> Result<PokemonCollection, Box<dyn std::error::Error>> {
) -> Result<crate::structs::PokemonRawCollection, Box<dyn std::error::Error>> {
// open the file in read only mode
let file = std::fs::File::open(file_path)?;
let reader = std::io::BufReader::new(file);
@ -234,9 +197,9 @@ fn read_pokemon_file(
}
fn transform_pokemon_data(
pokemon_collection: &std::collections::HashMap<String, Pokemon>,
) -> Vec<ProcessedPokemon> {
let mut processed_pokemons: Vec<ProcessedPokemon> = pokemon_collection
pokemon_collection: &std::collections::HashMap<String, crate::structs::PokemonRaw>,
) -> Vec<crate::structs::Pokemon> {
let mut processed_pokemons: Vec<crate::structs::Pokemon> = pokemon_collection
.iter()
.map(|(_key, p)| {
let mut forms = p
@ -257,7 +220,7 @@ fn transform_pokemon_data(
forms.insert(0, "regular".to_string());
}
ProcessedPokemon {
crate::structs::Pokemon {
// remove leading zeros from the pokedex number
pokedex: p.idx.trim_start_matches('0').to_string(),
// use the slug as the name

View file

@ -2,3 +2,5 @@ pub mod constants;
pub mod fetch;
pub mod list;
pub mod print;
pub mod structs;
pub mod validation;

View file

@ -1,15 +1,3 @@
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct Pokemon {
pokedex: String,
name: String,
forms: Vec<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
struct PokemonList {
pokemons: Vec<Pokemon>,
}
pub fn print_pokemon_list() -> Result<(), serde_json::Error> {
// open the file in read only mode with buffer
let file = std::fs::File::open(crate::constants::DATA_DIRECTORY.join("pokemon.json"))
@ -17,7 +5,7 @@ pub fn print_pokemon_list() -> Result<(), serde_json::Error> {
let reader = std::io::BufReader::new(file);
// parse json into pokemonlist struct
let pokemon_list: Vec<Pokemon> = serde_json::from_reader(reader)?;
let pokemon_list: Vec<crate::structs::Pokemon> = serde_json::from_reader(reader)?;
// iterate through the vector and print the pokedex and name
for pokemon in pokemon_list {
@ -35,7 +23,8 @@ pub fn print_pokemon_forms(pokemon_name: &str) -> std::io::Result<()> {
let reader = std::io::BufReader::new(file);
// parse json into pokemonlist struct
let pokemon_list: Vec<Pokemon> = serde_json::from_reader(reader).expect("Failed to parse JSON");
let pokemon_list: Vec<crate::structs::Pokemon> =
serde_json::from_reader(reader).expect("Failed to parse JSON");
// iterate through the list to find the specified pokemon and print its forms
let mut found = false;
@ -54,6 +43,8 @@ pub fn print_pokemon_forms(pokemon_name: &str) -> std::io::Result<()> {
if !found {
println!("No Pokemon found with the name '{}'.", pokemon_name);
println!("Hint: Do `rustmon list` to see all available Pokemon.")
} else {
println!("\nHint: Pass in `--form` when using subcommand `print` to see the specific form of a Pokemon!");
}
return Ok(());

View file

@ -13,7 +13,7 @@
- `no-title` - Do not print Pokemon name
- `pokedex` - Print Pokemon by Pokedex number
- `random` - Print a random Pokemon colorscript
- `shiny` - Print the shiny version of the colorscript
- `shiny` - Rate of printing the shiny version of the colorscript
*/
/// Pokemon Colorscripts written in Rust
@ -34,6 +34,11 @@ fn main() {
// invoke bigchungus fetch function
rustmon::fetch::fetch(extract_destination, verbose)
} else if let Some(list_args) = args.subcommand_matches("list") {
// list
// validate files first
rustmon::validation::validate_files();
let pokemon_name: &String = list_args.get_one::<String>("forms").unwrap();
if pokemon_name.is_empty() {
// list
@ -56,22 +61,19 @@ fn main() {
}
} else if let Some(print_args) = args.subcommand_matches("print") {
// print
// validate files first
rustmon::validation::validate_files();
// declare and define variables from arguments
let big: bool = print_args.get_flag("big");
let id = print_args.get_one::<String>("id").unwrap();
let name = print_args.get_one::<String>("name").unwrap();
let big = print_args.get_flag("big");
let pokedex: u16 = *print_args.get_one::<u16>("pokedex").unwrap();
let name: &String = print_args.get_one::<String>("name").unwrap();
let no_title: bool = print_args.get_flag("no-title");
let random: bool = print_args.get_flag("random");
let shiny: bool = print_args.get_flag("shiny");
let shiny: f32 = *print_args.get_one::<f32>("shiny").unwrap();
println!("Big: {}", big);
println!("ID: {}", id);
println!("Name: {}", name);
println!("No title: {}", no_title);
println!("Random: {}", random);
println!("Shiny: {}", shiny);
rustmon::print::print();
rustmon::print::print(big, pokedex, name, no_title, random, shiny);
}
}
@ -111,7 +113,8 @@ fn argument_parser() -> clap::ArgMatches {
.help("Print a list of forms of the specified Pokemon")
.short('f')
.long("forms")
.default_value(""),
.default_value("")
.hide_default_value(true),
)
.after_help(
"Tip: Use `grep` to search for a specific Pokemon form!
@ -124,21 +127,24 @@ For more advanced usage, use `less` or `more` to scroll through the list!",
clap::Command::new("print")
.about("Print a Pokemon colorscript")
// print/big
.arg(clap::arg!(-b --big "Print a bigger version of the colorscript"))
.arg(
clap::Arg::new("big")
.help("Print a bigger version of the colorscript")
.short('b')
.long("big")
.action(clap::ArgAction::SetTrue),
)
// print/name
.arg(
clap::Arg::new("name")
.help("Print Pokemon by name")
.short('n')
.long("name")
.default_value("")
.hide_default_value(true)
.conflicts_with("pokedex")
.conflicts_with("random"),
)
// print/random
.arg(
clap::arg!(-r --random "Print a random Pokemon colorscript")
.conflicts_with("name"),
)
// print/no-title
.arg(
clap::Arg::new("no-title")
@ -146,17 +152,37 @@ For more advanced usage, use `less` or `more` to scroll through the list!",
.long("no-title")
.action(clap::ArgAction::SetTrue),
)
// print/random
.arg(
clap::Arg::new("random")
.help("Print a random Pokemon colorscript")
.short('r')
.long("random")
.action(clap::ArgAction::SetTrue),
)
// print/pokedex
.arg(
clap::Arg::new("pokedex")
.help("Print Pokemon by Pokedex number")
.short('p')
.long("pokedex")
.value_parser(clap::value_parser!(u16).range(0..))
.default_value("0")
.hide_default_value(true)
.conflicts_with("name")
.conflicts_with("random"),
)
// print/shiny
.arg(clap::arg!(-s --shiny "Print the shiny version of the colorscript")),
.arg(
clap::Arg::new("shiny")
.help(
"Rate of printing the shiny version of the colorscript (e.g. 0.10 for 10% chance)",
)
.short('s')
.long("shiny")
.value_parser(clap::value_parser!(f32))
.default_value("0.10"),
),
)
// finalize
.get_matches();

View file

@ -1,3 +1,49 @@
pub fn print() {
println!("Hello, world!");
use std::io::Read;
pub fn print(big: bool, pokedex: u16, name: &String, no_title: bool, random: bool, shiny: f32) {
println!("Big: {}", big);
println!("pokedex: {}", pokedex);
println!("Name: {}", name);
println!("No title: {}", no_title);
println!("Random: {}", random);
println!("Shiny: {}", shiny);
// decide which function to call
// random, by pokedex or by name
if random {
// random
println!("Random");
} else if pokedex > 0 {
// by pokedex
println!("By pokedex");
} else {
// by name
println!("By name");
}
match find_pokemon_by_pokedex(&pokedex.to_string()) {
Ok(pokemon_name) => println!("Found Pokémon: {}", pokemon_name),
Err(e) => eprintln!("Error: {}", e),
}
}
fn find_pokemon_by_pokedex(pokedex_number: &str) -> Result<String, Box<dyn std::error::Error>> {
// read the file
let mut file = std::fs::File::open(crate::constants::DATA_DIRECTORY.join("pokemon.json"))?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
// deserialize into the struct
let pokemons: Vec<crate::structs::Pokemon> = serde_json::from_str(&contents)?;
// iterate through the list to find the specified pokemon
for pokemon in pokemons {
if pokemon.pokedex == pokedex_number {
// if found then return the name
return Ok(pokemon.name);
}
}
// if not found the return an error
return Err("Pokemon not found".into());
}

40
src/structs.rs Normal file
View file

@ -0,0 +1,40 @@
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct Slug {
pub eng: String,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct Forms {
// ignoring actual details in the forms and just capturing form names
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct Generation {
pub forms: std::collections::HashMap<String, Forms>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct PokemonRaw {
pub idx: String,
pub slug: Slug,
#[serde(rename = "gen-8")]
pub gen_8: Generation,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct PokemonRawCollection {
#[serde(flatten)]
pub entries: std::collections::HashMap<String, PokemonRaw>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct Pokemon {
pub pokedex: String,
pub name: String,
pub forms: Vec<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct PokemonCollection {
pub pokemons: Vec<Pokemon>,
}

64
src/validation.rs Normal file
View file

@ -0,0 +1,64 @@
pub fn validate_files() {
match validate_pokemon_json() {
Ok(_) => {}
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
};
match validate_colorscripts_directory() {
Ok(_) => {}
Err(e) => {
eprintln!("Error: {}", e);
std::process::exit(1);
}
};
}
fn validate_pokemon_json() -> Result<(), Box<dyn std::error::Error>> {
let file_path: std::path::PathBuf = crate::constants::DATA_DIRECTORY.join("pokemon.json");
// check if pokemon.json exists
if !crate::constants::DATA_DIRECTORY
.join("pokemon.json")
.exists()
{
return Err("`pokemon.json` does not exist. Please run the `fetch` subcommand.".into());
}
// open pokemon.json in read only mode
let file = std::fs::File::open(file_path)?;
let reader = std::io::BufReader::new(file);
// try to parse the json into an array of pokemons struct
let pokemon_data: Result<Vec<crate::structs::Pokemon>, serde_json::Error> =
serde_json::from_reader(reader);
match pokemon_data {
Ok(_) => return Ok(()),
Err(_) => {
return Err(format!(
"JSON structure is not correct. Please run the `fetch` subcommand."
)
.into())
}
}
}
fn validate_colorscripts_directory() -> Result<(), String> {
let base_path: std::path::PathBuf = crate::constants::DATA_DIRECTORY.join("colorscripts");
let subdirectories = ["big/regular", "big/shiny", "small/regular", "small/shiny"];
for subdirectory in subdirectories.iter() {
let path = base_path.join(subdirectory);
if !path.exists() {
return Err(format!(
"Directory does not exist. Please run the `fetch` subcommand."
));
}
}
return Ok(());
}