printing function complete

This commit is contained in:
Vomitblood 2024-04-22 01:36:05 +08:00
parent 68ad9c816b
commit fce6c7bd67
12 changed files with 347 additions and 579 deletions

29
Cargo.lock generated
View file

@ -246,12 +246,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "cipher"
version = "0.4.4"
@ -399,16 +393,6 @@ dependencies = [
"typenum",
]
[[package]]
name = "ctrlc"
version = "3.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345"
dependencies = [
"nix",
"windows-sys 0.52.0",
]
[[package]]
name = "deranged"
version = "0.3.11"
@ -1060,18 +1044,6 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "nix"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags 2.5.0",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]]
name = "nom"
version = "7.1.3"
@ -1607,7 +1579,6 @@ version = "0.1.0"
dependencies = [
"clap",
"crossterm",
"ctrlc",
"dirs",
"image",
"once_cell",

View file

@ -6,7 +6,6 @@ edition = "2021"
[dependencies]
clap = { version = "3.2.22", features = ["cargo"] }
crossterm = "0.27.0"
ctrlc = "3.4.4"
dirs = "5.0.1"
image = "0.25.1"
once_cell = "1.19.0"

View file

@ -1,60 +0,0 @@
use std::path::PathBuf;
use clap::{arg, value_parser, ArgAction, Command};
fn main() {
let matches = clap::command!() // requires `cargo` feature
.arg(arg!([name] "Optional name to operate on"))
.arg(
arg!(
-c --config <FILE> "Sets a custom config file"
)
// We don't have syntax yet for optional options, so manually calling `required`
.required(false)
.value_parser(value_parser!(PathBuf)),
)
.arg(arg!(
-d --debug ... "Turn debugging information on"
))
.subcommand(
Command::new("test")
.about("does testing things")
.arg(arg!(-l --list "lists test values").action(ArgAction::SetTrue)),
)
.get_matches();
// You can check the value provided by positional arguments, or option arguments
if let Some(name) = matches.get_one::<String>("name") {
println!("Value for name: {name}");
}
if let Some(config_path) = matches.get_one::<PathBuf>("config") {
println!("Value for config: {}", config_path.display());
}
// You can see how many times a particular flag or argument occurred
// Note, only flags can have multiple occurrences
match matches
.get_one::<u8>("debug")
.expect("Count's are defaulted")
{
0 => println!("Debug mode is off"),
1 => println!("Debug mode is kind of on"),
2 => println!("Debug mode is on"),
_ => println!("Don't be crazy"),
}
// You can check for the existence of subcommands, and if found use their
// matches just as you would the top level cmd
if let Some(matches) = matches.subcommand_matches("test") {
// "$ myapp test" was run
if matches.get_flag("list") {
// "$ myapp test -l" was run
println!("Printing testing lists...");
} else {
println!("Not printing testing lists...");
}
}
// Continued program logic goes here...
}

View file

@ -1,68 +0,0 @@
use serde::{Deserialize, Serialize};
use serde_json::{Result, Value};
use std::collections::HashMap;
use std::fs;
#[derive(Deserialize)]
struct Input {
#[serde(flatten)]
other: HashMap<String, Value>, // Capturing the rest of the data
gen_8: Option<Generation8>, // Making gen_8 optional
}
#[derive(Deserialize)]
struct Generation8 {
forms: HashMap<String, Value>,
}
#[derive(Serialize)]
struct Pokemon {
name: String,
id: String,
forms: Vec<String>,
}
fn main() -> Result<()> {
let data = fs::read_to_string("pokemon.json").expect("Unable to read file");
let input_pokemons: HashMap<String, Input> = serde_json::from_str(&data)?;
let mut output_pokemons: Vec<Pokemon> = Vec::new();
for (id, pokemon) in input_pokemons {
// Check if gen_8 data exists
let forms: Vec<String> = if let Some(gen_8) = pokemon.gen_8 {
gen_8
.forms
.keys()
.map(|key| {
if key == "$" {
"regular".to_string()
} else {
key.clone()
}
})
.collect()
} else {
// If there's no gen_8 data, you might want to handle it differently
// For now, let's just use an empty Vec
Vec::new()
};
// Proceed as before
output_pokemons.push(Pokemon {
name: pokemon.other["name"]["eng"]
.as_str()
.unwrap_or_default()
.to_string(),
id,
forms,
});
}
let output_json = serde_json::to_string_pretty(&output_pokemons)?;
println!("{}", output_json);
fs::write("output_pokemon.json", output_json).expect("Unable to write file");
Ok(())
}

View file

@ -1,323 +0,0 @@
fn main() {
let _bruh = "bruh";
}
// use std::fs;
// fn main() {
// let contents = fs::read_to_string("testing/testing.fuck").unwrap();
// let mut found: bool = false;
// for line in contents.lines() {
// match line {
// "1" | "2" => {
// found = true;
// break;
// }
// // if not found
// _ => found = false,
// }
// }
// if found == true {
// println!("Gotcha bitch");
// } else {
// println!("Never mind")
// }
// }
// use rand::{thread_rng, Rng};
// use std::io::{self, stdout, Write};
// use std::num::ParseIntError;
// #[derive(Debug)]
// enum Error {
// InvalidNumber(ParseIntError),
// OutOfRange,
// }
// fn main() {
// loop {
// let random_number: u8 = generate_random_number();
// loop {
// match get_user_number() {
// Ok(user_number) => {
// if user_number < random_number {
// println!("Too low!");
// } else if user_number > random_number {
// println!("Too high!");
// } else {
// println!("You guessed the correct number!");
// break;
// }
// }
// Err(e) => println!("{:?}", e),
// }
// }
// let user_choice = get_user_choice();
// if user_choice != "y" {
// break;
// }
// }
// }
// fn generate_random_number() -> u8 {
// let mut rng = thread_rng();
// rng.gen_range(1..101)
// }
// fn get_user_number() -> Result<u8, Error> {
// let string_input = read_user_input("Guess an integer between 1 and 100: ").unwrap();
// match string_input.trim().parse::<u8>() {
// Ok(value) if value >= 1 && value <= 100 => Ok(value),
// Ok(_) => Err(Error::OutOfRange),
// Err(e) => Err(Error::InvalidNumber(e)),
// }
// }
// fn get_user_choice() -> String {
// loop {
// let choice = read_user_input("Would you like to play again? (y/n): ").unwrap();
// if choice == "y" || choice == "n" {
// return choice;
// } else {
// println!("Invalid input. Please enter 'y' or 'n'.");
// }
// }
// }
// fn read_user_input(prompt: &str) -> io::Result<String> {
// let mut string_input = String::new();
// print!("{}", prompt);
// stdout().flush()?;
// io::stdin().read_line(&mut string_input)?;
// Ok(string_input.trim().to_string())
// }
// use rand::{thread_rng, Rng};
// use std::io::stdin;
// use std::io::{stdout, Write};
// fn main() {
// loop {
// // generate a random number
// let random_number: u8 = generate_random_number();
// // loop until they get it correct
// loop {
// // get the user input
// match get_user_number() {
// Ok(user_number) => {
// if user_number < random_number {
// println!("Too low!");
// } else if user_number > random_number {
// println!("Too high!");
// } else {
// println!("You guessed the correct number!");
// break;
// }
// }
// Err(e) => println!("{}", e),
// }
// }
// let user_choice = get_user_choice();
// if user_choice != "y" {
// break;
// }
// }
// }
// fn generate_random_number() -> u8 {
// let mut rng = thread_rng();
// return rng.gen_range(1..101);
// }
// fn get_user_number() -> Result<u8, String> {
// let mut string_input = String::new();
// print!("Guess an integer between 1 and 100: ");
// stdout().flush().unwrap();
// std::io::stdin().read_line(&mut string_input).unwrap();
// let parsed_input = string_input.trim().parse::<u8>();
// // check if the input is a valid number
// // this is validation
// match parsed_input {
// Ok(value) => {
// if value < 1 || value > 100 {
// return Err("Please enter an integer between 1 and 100.".to_string());
// } else {
// return Ok(value);
// }
// }
// Err(_) => {
// return Err("Please enter an integer between 1 and 100.".to_string());
// }
// }
// }
// fn get_user_choice() -> String {
// loop {
// let mut string_input = String::new();
// print!("Would you like to play again? (y/n): ");
// stdout().flush().unwrap();
// stdin().read_line(&mut string_input).unwrap();
// let choice = string_input.trim().to_string();
// if choice == "y" || choice == "n" {
// return choice;
// } else {
// println!("Invalid input. Please enter 'y' or 'n'.");
// }
// }
// }
// use ctrlc;
// use rand::{thread_rng, Rng};
// use std::io::stdin;
// use std::io::{stdout, Write};
// use std::sync::atomic::{AtomicBool, Ordering};
// use std::sync::Arc;
// fn main() {
// let running = Arc::new(AtomicBool::new(true));
// let r = running.clone();
// ctrlc::set_handler(move || {
// r.store(false, Ordering::SeqCst);
// println!("You cannot escape. Play the fucking game."); // Print message when Ctrl-C is pressed
// })
// .expect("Error setting Ctrl-C handler");
// while running.load(Ordering::SeqCst) {
// // generate a random number
// let random_number: u8 = generate_random_number();
// // loop until they get it correct
// loop {
// // get the user input
// match get_user_number() {
// Ok(user_number) => {
// if user_number < random_number {
// println!("Too low!");
// } else if user_number > random_number {
// println!("Too high!");
// } else {
// println!("You guessed the correct number!");
// break;
// }
// }
// Err(e) => println!("{}", e),
// }
// }
// let user_choice = get_user_choice();
// if user_choice != "y" {
// break;
// }
// }
// }
// fn generate_random_number() -> u8 {
// let mut rng = thread_rng();
// return rng.gen_range(1..101);
// }
// fn get_user_number() -> Result<u8, String> {
// let mut string_input = String::new();
// print!("Guess an integer between 1 and 100: ");
// stdout().flush().unwrap();
// std::io::stdin().read_line(&mut string_input).unwrap();
// let parsed_input = string_input.trim().parse::<u8>();
// // check if the input is a valid number
// // this is validation
// match parsed_input {
// Ok(value) => {
// if value < 1 || value > 100 {
// return Err("Please enter an integer between 1 and 100.".to_string());
// } else {
// return Ok(value);
// }
// }
// Err(_) => {
// return Err("Please enter an integer between 1 and 100.".to_string());
// }
// }
// }
// fn get_user_choice() -> String {
// loop {
// let mut string_input = String::new();
// print!("Would you like to play again? (y/n): ");
// stdout().flush().unwrap();
// stdin().read_line(&mut string_input).unwrap();
// let choice = string_input.trim().to_string();
// if choice == "y" || choice == "n" {
// return choice;
// } else {
// println!("Invalid input. Please enter 'y' or 'n'.");
// }
// }
// }
// use std::io::Write;
// fn main() {
// let mut string_input = String::new();
// print!("Enter a string: ");
// std::io::stdout().flush().unwrap();
// std::io::stdin().read_line(&mut string_input).unwrap();
// let mut trimmed_string = string_input.trim().to_string().push_str("hello");
// println!("You entered: {}", trimmed_string);
// }
// fn main() {
// let numbers = [1, 9, -2, 0, 23, 20, -7, 13, 37, 20, 56, -18, 20, 3];
// let max = *numbers.iter().max().unwrap();
// let min = *numbers.iter().min().unwrap();
// let sum: i32 = numbers.iter().sum();
// let mean = sum as f64 / numbers.len() as f64;
// assert_eq!(max, 56);
// assert_eq!(min, -18);
// assert_eq!(mean, 12.5);
// }
// fn main() {
// let numbers = [1, 9, -2, 0, 23, 20, -7, 13, 37, 20, 56, -18, 20, 3];
// let mut max: i32;
// let mut min: i32;
// let mean: f64;
// max = numbers[0];
// for n in numbers {
// if n > max {
// max = n;
// };
// }
// min = numbers[0];
// for n in numbers {
// if n < min {
// min = n;
// };
// }
// let mut sum = 0;
// for n in numbers {
// sum += n;
// }
// mean = sum as f64 / numbers.len() as f64;
// assert_eq!(max, 56);
// assert_eq!(min, -18);
// assert_eq!(mean, 12.5);
// }
// fn main() {
// let mut numbers = [1, 2, 3, 4, 5];
// for i in numbers.iter_mut() {
// *i += 1;
// println!("{}", &*i + 1);
// }
// }

View file

@ -1,16 +1,27 @@
pub static TARGET_URL: &str =
pub const TARGET_URL: &str =
"https://github.com/Vomitblood/pokesprite/archive/refs/heads/master.zip";
pub static DATA_DIRECTORY: once_cell::sync::Lazy<std::path::PathBuf> =
pub const DATA_DIRECTORY: once_cell::sync::Lazy<std::path::PathBuf> =
once_cell::sync::Lazy::new(|| {
dirs::data_dir()
.map(|dir| dir.join("rustmon"))
.expect("Data directory not found")
});
pub static CACHE_DIRECTORY: once_cell::sync::Lazy<std::path::PathBuf> =
pub const CACHE_DIRECTORY: once_cell::sync::Lazy<std::path::PathBuf> =
once_cell::sync::Lazy::new(|| {
dirs::cache_dir()
.map(|dir| dir.join("rustmon"))
.expect("Cache directory not found")
});
// pub const GENERATIONS: [(&str, (u16, u16)); 8] = [
// ("1", (1, 151)),
// ("2", (152, 251)),
// ("3", (252, 386)),
// ("4", (387, 493)),
// ("5", (494, 649)),
// ("6", (650, 721)),
// ("7", (722, 809)),
// ("8", (810, 905)),
// ];

View file

@ -9,11 +9,12 @@
## `print` - Print a Pokemon colorscript
- `big` - Print a bigger version of the colorscript
- `name` - Print Pokemon by name
- `no-title` - Do not print Pokemon name
- `pokedex` - Print Pokemon by Pokedex number
- `random` - Print a random Pokemon colorscript
- `form` - Print Pokemon by list of space-separated forms. Follows the order of the names/Pokedex number specified. If not specified, it will print the regular form.
- `hide-name` - Do not print Pokemon name
- `name` - Print Pokemon by list of space-separated names. Use `random` to print a random Pokemon.
- `pokedex` - Print Pokemon by list of space-separated Pokedex numbers. Use `0` to print a random Pokemon.
- `shiny` - Rate of printing the shiny version of the colorscript
- `spacing` - Number of spaces between colorscripts
*/
/// Pokemon Colorscripts written in Rust
@ -67,13 +68,15 @@ fn main() {
// declare and define variables from arguments
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: f32 = *print_args.get_one::<f32>("shiny").unwrap();
let forms: Vec<&String> = print_args.get_many("form").unwrap().collect();
let hide_name: bool = print_args.get_flag("hide-name");
let names: Vec<&String> = print_args.get_many("name").unwrap().collect();
let pokedexes: Vec<u16> = print_args.get_many("pokedex").unwrap().copied().collect();
let shiny_rate: f32 = *print_args.get_one::<f32>("shiny").unwrap();
let spacing: u8 = *print_args.get_one::<u8>("spacing").unwrap();
rustmon::print::print(big, pokedex, name, no_title, random, shiny);
// print
rustmon::print::print(big, forms, hide_name, names, pokedexes, shiny_rate, spacing);
}
}
@ -126,6 +129,7 @@ For more advanced usage, use `less` or `more` to scroll through the list!",
.subcommand(
clap::Command::new("print")
.about("Print a Pokemon colorscript")
.arg_required_else_help(true)
// print/big
.arg(
clap::Arg::new("big")
@ -134,43 +138,47 @@ For more advanced usage, use `less` or `more` to scroll through the list!",
.long("big")
.action(clap::ArgAction::SetTrue),
)
// print/form
.arg(
clap::Arg::new("form")
.help("Print Pokemon by list of space-separated forms. Follows the order of the names/Pokedex number specified. If not specified, it will print the regular form. Has no effect on random Pokemon.")
.short('f')
.long("form")
.default_value("regular")
.multiple_values(true)
.requires("name_or_pokedex"),
)
// print/hide-name
.arg(
clap::Arg::new("hide-name")
.help("Do not print Pokemon name")
.long("hide-name")
.action(clap::ArgAction::SetTrue),
)
// print/name
.arg(
clap::Arg::new("name")
.help("Print Pokemon by name")
.help("Print Pokemon by list of space-separated names. Use `random` to print a random Pokemon.")
.short('n')
.long("name")
.default_value("")
.hide_default_value(true)
.multiple_values(true)
.conflicts_with("pokedex")
.conflicts_with("random"),
)
// print/no-title
.arg(
clap::Arg::new("no-title")
.help("Do not print Pokemon name")
.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")
.help("Print Pokemon by list of space-separated Pokedex numbers. Use `0` to print a random Pokemon.")
.short('p')
.long("pokedex")
.value_parser(clap::value_parser!(u16).range(0..))
// TODO: use a dynamic range instead of 0..906
// try not to hardcode?
.value_parser(clap::value_parser!(u16).range(0..906))
.default_value("0")
.hide_default_value(true)
.multiple_values(true)
.conflicts_with("name")
.conflicts_with("random"),
)
// print/shiny
.arg(
@ -181,9 +189,25 @@ For more advanced usage, use `less` or `more` to scroll through the list!",
.short('s')
.long("shiny")
.value_parser(clap::value_parser!(f32))
.default_value("0.10"),
),
.default_value("0.00"),
)
// print/spacing
.arg(
clap::Arg::new("spacing")
.help(
"Number of spaces between colorscripts",
)
.long("spacing")
.value_parser(clap::value_parser!(u8).range(0..21))
.default_value("4"),
)
.group(
clap::ArgGroup::new("name_or_pokedex")
.args(&["name", "pokedex"])
.required(false),
)
)
.subcommand_required(true)
// finalize
.get_matches();
}

View file

@ -1,49 +1,293 @@
use rand::prelude::SliceRandom;
use rand::SeedableRng;
use std::io::BufRead;
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);
pub fn print(
big: bool,
forms: Vec<&String>,
hide_name: bool,
names: Vec<&String>,
pokedexes: Vec<u16>,
shiny_rate: f32,
spacing: u8,
) {
// 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");
if big == false
// uber fast random
&& forms.len() == 1
&& hide_name == false
&& (names.len() == 1 && pokedexes.len() == 1)
&& shiny_rate == 0.0
&& forms[0] == "regular"
&& (names[0] == "random" && pokedexes[0] == 0)
{
random_lite().unwrap();
} else {
// by name
println!("By name");
}
// convert list of names to list of pokedex numbers
let pokedexes = if !names[0].is_empty() {
let mut pokedexes: Vec<u16> = Vec::new();
for name in names {
match find_pokedex_by_pokemon(name) {
Ok(pokedex) => pokedexes.push(pokedex.parse().unwrap()),
Err(e) => {
println!("Error: {}", e);
std::process::exit(1);
}
}
}
pokedexes
} else {
pokedexes.clone()
};
match find_pokemon_by_pokedex(&pokedex.to_string()) {
Ok(pokemon_name) => println!("Found Pokémon: {}", pokemon_name),
Err(e) => eprintln!("Error: {}", e),
// process the forms list
// the length of the forms list should be the same as the pokedexes list, resize with `regular` if different length
// if the form is not available for the pokemon then print the available forms and exit
let forms = process_forms_list(&pokedexes, forms);
// generate a list of slugs
let slugs = generate_slug_list(big, forms, &pokedexes, shiny_rate);
println!("{:?}", slugs);
print_name(&slugs);
print_ascii_side_by_side(&slugs, spacing).unwrap();
}
}
fn find_pokemon_by_pokedex(pokedex_number: &str) -> Result<String, Box<dyn std::error::Error>> {
fn random_lite() -> std::io::Result<()> {
let path = crate::constants::DATA_DIRECTORY.join("colorscripts/small/regular/");
let mut files: Vec<std::path::PathBuf> = Vec::new();
for entry in std::fs::read_dir(&path)? {
let dir_entry = entry?;
files.push(dir_entry.path());
}
let mut rng = rand::rngs::SmallRng::from_entropy();
if let Some(random_file) = files.choose(&mut rng) {
if let Some(file_name) = random_file.file_name() {
match file_name.to_str() {
Some(name) => println!("{}", name),
None => println!("Invalid UTF-8 sequence in file name"),
}
}
match std::fs::read_to_string(random_file) {
Ok(file_data) => {
println!("{}", file_data);
Ok(())
}
Err(e) => {
println!("Failed to read file contents: {}", e);
Err(e)
}
}
} else {
println!("No files found in the directory");
Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"No files available",
))
}
}
fn get_pokemon_data(pokedex_number: u16) -> crate::structs::Pokemon {
// read the file
let mut file = std::fs::File::open(crate::constants::DATA_DIRECTORY.join("pokemon.json"))?;
let mut file =
std::fs::File::open(crate::constants::DATA_DIRECTORY.join("pokemon.json")).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents)?;
file.read_to_string(&mut contents).unwrap();
// deserialize into the struct
let pokemons: Vec<crate::structs::Pokemon> = serde_json::from_str(&contents)?;
let pokemons: Vec<crate::structs::Pokemon> = serde_json::from_str(&contents).unwrap();
// 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);
// get the pokemon data
// remember that the pokedex number is 1-indexed
// gawdamn it
let pokemon_data: crate::structs::Pokemon =
pokemons.get(pokedex_number as usize - 1).unwrap().clone();
// return the data
return pokemon_data;
}
fn find_pokemon_by_pokedex(
pokedex_number_string: &str,
) -> Result<String, Box<dyn std::error::Error>> {
// handle random
if pokedex_number_string == "0" {
return Ok("random".to_string());
} else {
// 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)?;
let pokedex_number = pokedex_number_string.parse::<usize>().unwrap();
let pokemon_data = pokemons.get(pokedex_number).unwrap();
return Ok(pokemon_data.name.clone());
}
}
fn find_pokedex_by_pokemon(pokemon_name: &str) -> Result<String, Box<dyn std::error::Error>> {
// handle random
if pokemon_name == "random" {
return Ok("0".to_string());
} else {
// 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.name == pokemon_name {
// if found then return the pokedex number
return Ok(pokemon.pokedex);
}
}
// if not found the return an error
return Err(format!("Pokemon {} not found", pokemon_name).into());
}
}
fn is_shiny(shiny_rate: f32) -> bool {
// generate a random number between 0 and 1
let random_number = rand::random::<f32>();
// if the random number is less than the shiny rate then return true
return random_number < shiny_rate;
}
fn process_forms_list(pokedexes: &Vec<u16>, forms: Vec<&String>) -> Vec<String> {
let mut forms_processed: Vec<String> = forms.iter().map(|s| s.to_string()).collect();
// ensure forms_processed has the same length as pokedexes
forms_processed.resize_with(pokedexes.len(), || "regular".to_string());
for i in 0..pokedexes.len() {
let pokemon = get_pokemon_data(pokedexes[i]);
let form = &forms_processed[i];
if !pokemon.forms.contains(&form.to_string()) {
// iterate and print out the available forms
// consider using crate::list::print_pokemon_forms(pokemon_name)
println!("Available forms for {}:", pokemon.name);
for available_form in &pokemon.forms {
println!(" - {}", available_form);
}
std::process::exit(1);
}
}
// if not found the return an error
return Err("Pokemon not found".into());
return forms_processed;
}
fn slug_generator(big: bool, form: String, name: String, shiny_rate: f32) -> std::path::PathBuf {
// big is just a boolean, convert it to big or small
// form is a string, if `regular` then replace with empty string. else keep it as is.
// name is a string, should be cleaned up already. there should be no `random` as a name should be generated before this.
// shiny_rate is a float, let it be
// if big is true then use big, else use small
let big: String = if big {
"big".to_string()
} else {
"small".to_string()
};
// if form is regular then replace with empty string
let form: String = if form == "regular" {
"".to_string()
} else {
format!("-{}", form)
};
// determine if shiny directory is to be used
let shiny_directory: String = if is_shiny(shiny_rate) {
"shiny".to_string()
} else {
"regular".to_string()
};
// construct the path using PathBuf
let mut path = std::path::PathBuf::new();
path.push(crate::constants::DATA_DIRECTORY.join("colorscripts"));
path.push(format!("{}", big));
path.push(shiny_directory);
path.push(format!("{}{}", name, form));
return path;
}
fn generate_slug_list(
big: bool,
forms: Vec<String>,
pokedexes: &Vec<u16>,
shiny_rate: f32,
) -> Vec<std::path::PathBuf> {
let mut slugs: Vec<std::path::PathBuf> = Vec::new();
// iterate through the pokedexes to generate the slugs with the complementing form
for i in 0..pokedexes.len() {
let pokemon = get_pokemon_data(pokedexes[i]);
let form = &forms[i];
let slug = slug_generator(big, form.to_string(), pokemon.name, shiny_rate);
slugs.push(slug);
}
return slugs;
}
fn print_name(paths: &Vec<std::path::PathBuf>) {
let last_parts: Vec<&str> = paths
.iter()
.filter_map(|path| path.file_name())
.filter_map(|os_str| os_str.to_str())
.collect();
let output = last_parts.join(", ");
println!("{}", output);
}
fn print_ascii_side_by_side(paths: &Vec<std::path::PathBuf>, spacing: u8) -> std::io::Result<()> {
// open all files and create BufReaders
let mut readers: Vec<_> = paths
.iter()
.map(|path| std::fs::File::open(path))
.filter_map(|result| result.ok())
.map(|file| std::io::BufReader::new(file))
.collect();
// create a string for spacing
let separator = " ".repeat(spacing as usize);
// one line by one line
let mut lines: Vec<String> = vec![];
loop {
lines.clear();
for reader in &mut readers {
let mut line = String::new();
if reader.read_line(&mut line)? > 0 {
lines.push(line.trim_end().to_string());
} else {
// End of file reached
return Ok(());
}
}
println!("{}", lines.join(&separator));
}
}

View file

@ -27,7 +27,7 @@ pub struct PokemonRawCollection {
pub entries: std::collections::HashMap<String, PokemonRaw>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct Pokemon {
pub pokedex: String,
pub name: String,

View file

@ -1,8 +0,0 @@
asdf
3
4
5
6
1
7
69

View file

@ -1,22 +0,0 @@
import random
# generate a random integer between 1 and 100
random_number = random.randint(1, 100)
user_input = input("Guess an integer between 1 and 100: ")
# convert the user input to an integer
try:
user_input = int(user_input)
except ValueError:
print("Please enter a valid number")
exit()
if user_input < 1 or user_input > 100:
print("Please enter a number between 1 and 100")
exit()
elif random_number == user_input:
print("You guessed correctly!")
else:
# use f strings to format the string
print(f"Sorry, the number was {random_number}. Try again next time!")

View file