~jacqueline/pokemon

7e64f114048f84651fadbcca3419e406c110af03 — jacqueline leykam 1 year, 2 months ago d8cdb31
format nicely
1 files changed, 73 insertions(+), 62 deletions(-)

M src/bin/pack-resources.rs
M src/bin/pack-resources.rs => src/bin/pack-resources.rs +73 -62
@@ 1,11 1,13 @@
use std::collections::HashMap;
use std::fs::read_dir;
use std::{env, fs::File};
use std::io::{prelude::*, BufReader, BufWriter};
use minicbor::bytes::ByteArray;
use minicbor_io::Writer;
use pokemon::pokedex::{self, Pokemon, Type, StatData, MoveListChunk, Move, LearnableMove, LearnCondition};
use pokemon::pokedex::{
    self, LearnCondition, LearnableMove, Move, MoveListChunk, Pokemon, StatData, Type,
};
use serde_json::Value;
use std::collections::HashMap;
use std::fs::read_dir;
use std::io::{prelude::*, BufReader, BufWriter};
use std::{env, fs::File};

#[derive(Debug)]
struct ParseError(String);


@@ 25,11 27,11 @@ fn main() {
    for f in files {
        let path = match f.ok().map(|f| f.path()) {
            Some(p) => p,
            None => continue
            None => continue,
        };
        let json_filename = match path.extension().and_then(|ext| ext.to_str()) {
            Some("json") => path,
            _ => continue
            _ => continue,
        };
        let bmp_filename = json_filename.with_extension("bmp");



@@ 58,13 60,13 @@ fn parse_movelist(json: &Value) -> Result<Vec<MoveListChunk>, ParseError> {
    for m in json.as_array().unwrap_or(&Vec::new()) {
        let parsed = match parse_learnable_move(m) {
            Ok(p) => p,
            Err(e) => return Err(ParseError(format!("failed to parse move: {:?}", e)))
            Err(e) => return Err(ParseError(format!("failed to parse move: {:?}", e))),
        };
        for i in parsed {
            if current_chunk_i == 16 {
                all_chunks.push(MoveListChunk{
                all_chunks.push(MoveListChunk {
                    is_final_chunk: false,
                    moves: current_chunk
                    moves: current_chunk,
                });
                current_chunk = [None; 16];
                current_chunk_i = 0;


@@ 81,9 83,9 @@ fn parse_movelist(json: &Value) -> Result<Vec<MoveListChunk>, ParseError> {
    }

    // Finish the final chunk.
    all_chunks.push(MoveListChunk{
    all_chunks.push(MoveListChunk {
        is_final_chunk: true,
        moves: current_chunk
        moves: current_chunk,
    });

    return Ok(all_chunks);


@@ 92,33 94,44 @@ fn parse_movelist(json: &Value) -> Result<Vec<MoveListChunk>, ParseError> {
fn parse_learnable_move(json: &Value) -> Result<Vec<LearnableMove>, ParseError> {
    let parts: Vec<&str> = match json["move"]["url"].as_str() {
        Some(i) => i.split("/").collect(),
        None => return Err(ParseError("missing move id".to_string()))
        None => return Err(ParseError("missing move id".to_string())),
    };
    let id: u16 = match parts[parts.len() - 2].parse() {
        Ok(i) => i,
        Err(e) => return Err(ParseError(format!("failed to parse id: {}", e)))
        Err(e) => return Err(ParseError(format!("failed to parse id: {}", e))),
    };
    let mut moves = Vec::new();
    for method in json["version_group_details"].as_array().unwrap_or(&Vec::new()) {
        moves.push(LearnableMove{
    for method in json["version_group_details"]
        .as_array()
        .unwrap_or(&Vec::new())
    {
        moves.push(LearnableMove {
            id,
            condition: match method["move_learn_method"].as_str() {
                Some("level-up") => LearnCondition::LevelUp{
                    level: match method["level_learned_at"].as_u64().map(|i| u8::try_from(i).ok()).flatten() {
                Some("level-up") => LearnCondition::LevelUp {
                    level: match method["level_learned_at"]
                        .as_u64()
                        .map(|i| u8::try_from(i).ok())
                        .flatten()
                    {
                        Some(l) => l,
                        None => return Err(ParseError("missing or malformed level up method".to_string()))
                    }
                        None => {
                            return Err(ParseError(
                                "missing or malformed level up method".to_string(),
                            ))
                        }
                    },
                },
                Some("machine") => LearnCondition::Machine,
                Some(m) => return Err(ParseError(format!("unknown learn method {}", m))),
                None => return Err(ParseError("missing learn method".to_string()))
            }
                None => return Err(ParseError("missing learn method".to_string())),
            },
        })
    }
    return match moves.len() {
        0 => Err(ParseError("move had no learn methods".to_string())),
        _ => Ok(moves)
    }
        _ => Ok(moves),
    };
}

fn parse_move(json: Value) -> Result<Move, &'static str> {


@@ 135,8 148,8 @@ fn parse_pokemon(json: &Value, bitmap: &[u8; 578]) -> Result<Pokemon, &'static s
                i += 1;
            }
            name
        },
        None => return Err("name was missing")
        }
        None => return Err("name was missing"),
    };

    let mut types = [Option::None, Option::None];


@@ 147,45 160,46 @@ fn parse_pokemon(json: &Value, bitmap: &[u8; 578]) -> Result<Pokemon, &'static s
                    Some(1) => 0,
                    Some(2) => 1,
                    None => return Err("missing type slot"),
                    _ => return Err("invalid type slot")
                    _ => return Err("invalid type slot"),
                };
                types[slot] = match t["type"].as_str() {
                    Some(val) => {
                        match type_from_string(val) {
                            Ok(t) => Some(t),
                            Err(_) => return Err("failed to parse type")
                        }
                    }
                    None => None
                    Some(val) => match type_from_string(val) {
                        Ok(t) => Some(t),
                        Err(_) => return Err("failed to parse type"),
                    },
                    None => None,
                }
            }
        }
        None => return Err("no types found")
        None => return Err("no types found"),
    }

    let stats: HashMap<_, _> = match json["stats"].as_array() {
        Some(all_stats) => all_stats.iter().flat_map(|j| parse_as_stat_data(j)).collect(),
        None => return Err("missing stats")
        Some(all_stats) => all_stats
            .iter()
            .flat_map(|j| parse_as_stat_data(j))
            .collect(),
        None => return Err("missing stats"),
    };

     Ok(pokedex::Pokemon {
    Ok(pokedex::Pokemon {
        id: match parse_as_u8(&json["id"]) {
            Some(i) => i,
            None => return Err("missing id")
            None => return Err("missing id"),
        },
        name,
        type_primary: match types[0] {
            Some(t) => t,
            None => return Err("no primary type given")
            None => return Err("no primary type given"),
        },
        type_secondary: types[1],
        capture_rate: match parse_as_u8(&json["species"]["capture_rate"]) {
            Some(i) => i,
            None => return Err("missing capture rate")
            None => return Err("missing capture rate"),
        },
        base_experience: match parse_as_u8(&json["id"]) {
            Some(i) => i,
            None => return Err("missing base experience")
            None => return Err("missing base experience"),
        },
        hp: stats["hp"],
        attack: stats["attack"],


@@ 198,34 212,31 @@ fn parse_pokemon(json: &Value, bitmap: &[u8; 578]) -> Result<Pokemon, &'static s
}

fn parse_as_u8(json: &Value) -> Option<u8> {
        return match json.as_u64().map(|i| u8::try_from(i)) {
            Some(i) => {
                match i {
                    Ok(i) => Some(i),
                    Err(_) => None
                }
            },
            None => None
        }
    return match json.as_u64().map(|i| u8::try_from(i)) {
        Some(i) => match i {
            Ok(i) => Some(i),
            Err(_) => None,
        },
        None => None,
    };
}

fn parse_as_stat_data(json: &Value) -> Option<(&str, StatData)> {
    Some((
        match json["stat"].as_str() {
            Some(i) => i,
            None => return None
            None => return None,
        },
        StatData {
            base_value: match json["base_stat"].as_u64().map(|i| u16::try_from(i)) {
                Some(i) => {
                    match i {
                        Ok(i) => i,
                        Err(_) => return None
                    }
                Some(i) => match i {
                    Ok(i) => i,
                    Err(_) => return None,
                },
                None => return None
            }
        }))
                None => return None,
            },
        },
    ))
}

fn type_from_string(s: &str) -> Result<Type, &str> {


@@ 248,6 259,6 @@ fn type_from_string(s: &str) -> Result<Type, &str> {
        "dragon" => Ok(Type::Dragon),
        "dark" => Ok(Type::Dark),
        "fairy" => Ok(Type::Fairy),
        _ => Err("unknown type")
        _ => Err("unknown type"),
    }
}
\ No newline at end of file
}