printing function complete
This commit is contained in:
parent
68ad9c816b
commit
fce6c7bd67
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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...
|
||||
}
|
|
@ -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(())
|
||||
}
|
|
@ -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);
|
||||
// }
|
||||
// }
|
|
@ -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)),
|
||||
// ];
|
||||
|
|
88
src/main.rs
88
src/main.rs
|
@ -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();
|
||||
}
|
||||
|
|
294
src/print.rs
294
src/print.rs
|
@ -1,33 +1,147 @@
|
|||
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")).unwrap();
|
||||
let mut contents = String::new();
|
||||
file.read_to_string(&mut contents).unwrap();
|
||||
|
||||
// deserialize into the struct
|
||||
let pokemons: Vec<crate::structs::Pokemon> = serde_json::from_str(&contents).unwrap();
|
||||
|
||||
// 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();
|
||||
|
@ -38,12 +152,142 @@ fn find_pokemon_by_pokedex(pokedex_number: &str) -> Result<String, Box<dyn std::
|
|||
|
||||
// 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 pokemon.name == pokemon_name {
|
||||
// if found then return the pokedex number
|
||||
return Ok(pokemon.pokedex);
|
||||
}
|
||||
}
|
||||
|
||||
// if not found the return an error
|
||||
return Err("Pokemon not found".into());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
asdf
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
1
|
||||
7
|
||||
69
|
|
@ -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!")
|
Loading…
Reference in a new issue