mlemesle / rustemon

A wrapper library for PokeApi, written in Rust
MIT License
27 stars 10 forks source link

Unable to get certain types #1

Closed Rdlenke closed 2 years ago

Rdlenke commented 2 years ago

Good day @mlemesle. Nice lib you got there.

I'm learning rust and was trying to use this wrapper to make something pokémon related, but I ran into a problem. It seems that reqwest or serde have some problems deserializing some pokémon types. Ex:

Cargo.toml

[package]
name = "rustemon-test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rustemon = "0.1.0"

src/main.rs

use rustemon::api::endpoint;

fn main() {
    println!("{:#?} ", endpoint::pokemon::type_::get_by_name(&"steel"));
}

Output:

Err(
    reqwest::Error {
        kind: Decode,
        source: Error("invalid type: map, expected a sequence", line: 1, column: 5011),
    },
)

Using skip_deserializing I was able to remove field by field from the Type model and found that both damage_relations and past_damage_relations are problematic, but I couldn't really understand why. Could you help?

Thanks in advance!

R.L.

Rdlenke commented 2 years ago

UPDATE: Turns out that the error was right in from of my eyes.

The Type model describes past_damage_relations as below:

pub past_damage_relations: Vec<TypeRelationsPast>

And TypeRelationsPast is

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct TypeRelationsPast {
    pub generation: NamedAPIResource<Generation>,
    pub damage_relations: Vec<TypeRelations>
}

The problem is that damage_relations is no Vec. Here's a snippet of the results that requesting the type steel gives using postman:

"past_damage_relations": [
    {
      "damage_relations": { // <--- Object, not list
        "double_damage_from": [
          {
            "name": "fighting",
            "url": "https://pokeapi.co/api/v2/type/2/"
          },
          {
            "name": "ground",
            "url": "https://pokeapi.co/api/v2/type/5/"
          },
          {
            "name": "fire",
            "url": "https://pokeapi.co/api/v2/type/10/"
          }
        ],

Simply changing TypeRelationsPast to the struct below fixes the problem.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct TypeRelationsPast {
    pub generation: NamedAPIResource<Generation>,
    pub damage_relations: TypeRelations
}

Curiously, the PokéAPI documentation does describe damage_relations in TypeRelationsPast as a list. I'll open an issue in their repository, and hopefully the docs will be fixed soon. Meanwhile, do you want me to open a PR fixing this model?

mlemesle commented 2 years ago

Hey @Rdlenke ! Thanks for reaching out !

Indeed, the documentation in PokeApi seems to be outdated, you're right to open an issue on their side.

You were also right to open an issue here as well. I agree with you on the fix. You can do it if you want to or I can do it later in the day, just let me know !

Also, I am learning Rust too. Feel free to give me some feedback about the code, architecture etc etc...

I stay available if you need, and thanks again for the help !

Rdlenke commented 2 years ago

@mlemesle I've created the PR and also created the issue on the PokeAPI repo. They've already fixed the docs website.

Thanks again for this awesome wrapper, and for the help. As I use it (and learn rust), I'll surely come up with suggestions.

mlemesle commented 2 years ago

I merged it! Thanks for the help there.

Feel free to contact me anytime :)