This commit is contained in:
Vomitblood 2024-03-24 22:17:14 +08:00
parent 733b9650e6
commit 33691e38df
3 changed files with 186 additions and 253 deletions

136
Cargo.lock generated
View file

@ -2,59 +2,12 @@
# It is not intended for manual editing.
version = 3
[[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.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "3.2.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"atty",
"bitflags",
"clap_lex",
"indexmap",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "getrandom"
version = "0.2.12"
@ -66,31 +19,6 @@ dependencies = [
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.10"
@ -104,16 +32,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "os_str_bytes"
version = "6.6.1"
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "pokerust"
version = "0.1.0"
dependencies = [
"clap",
"once_cell",
"rand",
"serde",
"serde_json",
@ -210,38 +138,17 @@ dependencies = [
"serde",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "2.0.53"
version = "2.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[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 = "unicode-ident"
version = "1.0.12"
@ -253,34 +160,3 @@ name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -6,7 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
clap = "3.0"
rand = "0.8"
once_cell = "1.8.0"

View file

@ -1,139 +1,196 @@
use clap::{App, Arg};
use rand::{thread_rng, Rng};
use serde::{Deserialize, Serialize};
use std::fs;
use std::{fs::File, io::Read, path::Path};
use rand::Rng;
use std::io::prelude::*;
fn main() {
let matches = App::new("pokemon-colorscripts")
.version("0.1.0")
.author("Your Name")
.about("Displays Pokemon in your terminal")
.arg(
Arg::with_name("list")
.short('l')
.long("list")
.help("Print list of all Pokemon"),
)
.arg(
Arg::with_name("name")
.short('n')
.long("name")
.value_name("NAME")
.help("Select Pokémon by name.")
.takes_value(true),
)
.arg(
Arg::with_name("form")
.short('f')
.long("form")
.value_name("FORM")
.help("Show an alternate form of a Pokémon")
.takes_value(true),
)
.arg(
Arg::with_name("shiny")
.short('s')
.long("shiny")
.help("Show the shiny version of the Pokémon instead"),
)
.arg(
Arg::with_name("big")
.short('b')
.long("big")
.help("Show a larger version of the sprite"),
)
.arg(
Arg::with_name("random")
.short('r')
.long("random")
.value_name("GEN")
.help("Show a random Pokémon. Optionally specify a generation.")
.takes_value(true),
)
// Add more arguments as per your Python script
.get_matches();
// set global constants
const PROGRAM: once_cell::sync::Lazy<std::path::PathBuf> =
once_cell::sync::Lazy::new(|| std::env::current_exe().unwrap());
if matches.is_present("list") {
list_pokemon_names();
const PROGRAM_DIR: once_cell::sync::Lazy<std::path::PathBuf> = once_cell::sync::Lazy::new(|| {
std::path::PathBuf::from(std::env::current_exe().unwrap().parent().unwrap())
});
const COLORSCRIPTS_DIR: once_cell::sync::Lazy<std::path::PathBuf> =
once_cell::sync::Lazy::new(|| PROGRAM_DIR.join("colorscripts"));
const REGULAR_SUBDIR: &str = "regular";
const SHINY_SUBDIR: &str = "shiny";
const LARGE_SUBDIR: &str = "large";
const SMALL_SUBDIR: &str = "small";
const SHINY_RATE: f64 = 1.0 / 128.0;
const GENERATIONS: [(&str, (u32, u32)); 8] = [
("1", (1, 151)),
("2", (152, 251)),
("3", (252, 386)),
("4", (387, 493)),
("5", (494, 649)),
("6", (650, 721)),
("7", (722, 809)),
("8", (810, 898)),
];
fn print_file(filepath: &std::path::Path) -> std::io::Result<()> {
let file = std::fs::File::open(filepath)?;
let reader = std::io::BufReader::new(file);
for line in reader.lines() {
println!("{}", line?);
}
if let Some(name) = matches.value_of("name") {
let shiny = matches.is_present("shiny");
let is_large = matches.is_present("big");
let form = matches.value_of("form");
show_pokemon_by_name(name, shiny, is_large, form);
} else if matches.is_present("random") {
let generation = matches.value_of("random");
let shiny = matches.is_present("shiny");
let is_large = matches.is_present("big");
show_random_pokemon(generation, shiny, is_large);
}
// Handle other commands similarly
Ok(())
}
#[derive(Serialize, Deserialize)]
struct Pokemon {
name: String,
// Define other fields as needed
}
fn list_pokemon_names(filepath: &std::path::Path) -> std::io::Result<()> {
let file = std::fs::File::open(filepath)?;
let reader = std::io::BufReader::new(file);
let pokemon_json: serde_json::Value = serde_json::from_reader(reader)?;
fn load_pokemon_data() -> Vec<Pokemon> {
let path = Path::new("pokemon.json");
let mut file = File::open(&path).expect("File not found");
let mut contents = String::new();
file.read_to_string(&mut contents)
.expect("Failed to read file");
let mut count = 0;
serde_json::from_str(&contents).expect("Failed to parse JSON")
}
fn list_pokemon_names() {
let pokemon_list = load_pokemon_data();
for pokemon in pokemon_list {
println!("{}", pokemon.name);
}
}
fn print_file(filepath: &str) {
match fs::read_to_string(filepath) {
Ok(contents) => println!("{}", contents),
Err(e) => eprintln!("Error reading file: {}", e),
}
}
fn show_pokemon_by_name(name: &str, shiny: bool, is_large: bool, form: Option<&str>) {
let color_subdir = if shiny { "shiny" } else { "regular" };
let size_subdir = if is_large { "large" } else { "small" };
let mut pokemon_name = name.to_string();
if let Some(f) = form {
pokemon_name.push_str("-");
pokemon_name.push_str(f);
if let serde_json::Value::Array(array) = pokemon_json {
for pokemon in array {
if let Some(name) = pokemon.get("name") {
if let serde_json::Value::String(name_str) = name {
println!("{}", name_str);
count += 1;
}
}
}
}
let filepath = format!(
"{}/{}/{}/{}",
"path_to_colorscripts_dir", size_subdir, color_subdir, pokemon_name
);
println!("Total: {} Pokémons", count);
println!("Showing: {}", pokemon_name);
print_file(&filepath);
Ok(())
}
fn show_random_pokemon(generation: Option<&str>, shiny: bool, is_large: bool) {
let pokemon_list = load_pokemon_data();
// Simplified: Add logic to filter Pokémon based on the generation range
let mut rng = thread_rng();
let pokemon_index = rng.gen_range(0..pokemon_list.len());
let pokemon_name = &pokemon_list[pokemon_index].name;
fn show_pokemon_by_name(
name: &str,
show_title: bool,
shiny: bool,
is_large: bool,
form: Option<&str>,
) -> std::io::Result<()> {
// set variables
let base_path = COLORSCRIPTS_DIR;
let color_subdir = if shiny { SHINY_SUBDIR } else { REGULAR_SUBDIR };
let size_subdir = if is_large { LARGE_SUBDIR } else { SMALL_SUBDIR };
// Determine shininess based on a random chance or if explicitly requested
let is_shiny = if shiny {
true
let file = std::fs::File::open(PROGRAM_DIR.join("pokemon.json"))?;
let reader = std::io::BufReader::new(file);
let pokemon_json: serde_json::Value = serde_json::from_reader(reader)?;
let pokemon_names: Vec<&str> = pokemon_json
.as_array()
.unwrap()
.iter()
.map(|pokemon| pokemon["name"].as_str().unwrap())
.collect();
if !pokemon_names.contains(&name) {
println!("Invalid pokemon {}", name);
std::process::exit(1);
}
let mut name = name.to_string();
if let Some(form) = form {
let forms: Vec<&str> = pokemon_json
.as_array()
.unwrap()
.iter()
.filter(|pokemon| pokemon["name"].as_str().unwrap() == name)
.flat_map(|pokemon| pokemon["forms"].as_array().unwrap().iter())
.map(|form| form.as_str().unwrap())
.collect();
let alternate_forms: Vec<&str> =
forms.iter().filter(|&f| *f != "regular").cloned().collect();
if alternate_forms.contains(&form) {
name.push_str(&format!("-{}", form));
} else {
println!("Invalid form '{}' for pokemon {}", form, name);
if alternate_forms.is_empty() {
println!("No alternate forms available for {}", name);
} else {
println!("Available alternate forms are");
for form in alternate_forms {
println!("- {}", form);
}
}
std::process::exit(1);
}
}
let pokemon_file = base_path.join(size_subdir).join(color_subdir).join(&name);
if show_title {
if shiny {
println!("{} (shiny)", name);
} else {
println!("{}", name);
}
}
print_file(&pokemon_file)
}
fn show_random_pokemon(
generations: &str,
show_title: bool,
shiny: bool,
is_large: bool,
) -> std::io::Result<()> {
let mut rng = rand::thread_rng();
let (start_gen, end_gen) = if generations.is_empty() {
("1", "8")
} else if generations.contains(",") {
let gens: Vec<&str> = generations.split(",").collect();
let gen = gens[rng.gen_range(0..gens.len())];
(gen, gen)
} else if generations.contains("-") {
let gens: Vec<&str> = generations.split("-").collect();
(gens[0], gens[1])
} else {
rng.gen_bool(1.0 / 128.0)
(generations, generations)
};
show_pokemon_by_name(pokemon_name, is_shiny, is_large, None);
let file = std::fs::File::open(PROGRAM_DIR.join("pokemon.json"))?;
let reader = std::io::BufReader::new(file);
let pokemon_json: serde_json::Value = serde_json::from_reader(reader)?;
let pokemon: Vec<String> = pokemon_json
.as_array()
.unwrap()
.iter()
.map(|p| p["name"].as_str().unwrap().to_string())
.collect();
let generations_map: std::collections::HashMap<_, _> = GENERATIONS.iter().cloned().collect();
if let Some((start_idx, end_idx)) = generations_map.get(start_gen) {
let random_idx = rng.gen_range(*start_idx..=*end_idx);
let random_pokemon = &pokemon[random_idx as usize - 1];
let shiny = if !shiny {
rng.gen::<f64>() <= SHINY_RATE
} else {
shiny
};
show_pokemon_by_name(random_pokemon, show_title, shiny, is_large, None)?;
} else {
println!("Invalid generation '{}'", generations);
std::process::exit(1);
}
Ok(())
}
fn main() {
// println!("{}", PROGRAM.display());
// println!("{}", PROGRAM_DIR.display());
// println!("{}", COLORSCRIPTS_DIR.display());
// show_pokemon_by_name("eevee", false, false, false, Some("gmax")).unwrap();
show_random_pokemon("1-999", true, false, false);
}