not-fl3 / nanoserde

Serialisation library with zero dependencies

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to fix this avoiding serde?

frederikhors opened this issue · comments

Hi people! Thanks for your amazing work! I'm new to Rust and I'm using serde only to do this easy thing. I think I can use nanoserde instead but I don't know how.

I'm using serde like this:

use serde::Deserialize;

#[derive(Deserialize, Clone)]
pub struct Player {
    pub team: Team,
}

#[derive(Deserialize, Clone)]
pub struct Team {
    pub id: String,
    // others here
}

// ...

if api_call.status().is_success() {
    match serde_json::from_slice::<Player>(
        &hyper::body::to_bytes(api_call.into_body()).await.unwrap(),
    ) {
        Ok(player) => {
            // use player.team here

            // do something else
        }
        Err(err) => {
            eprintln!("{err}");
        }
    }
}

I tried with:

match nanoserde::DeBin::de_bin::<Player>(
   &hyper::body::to_bytes(api_call.into_body()).await.unwrap(),
) {
  // ...
}

with no luck: it doesn't like the generics.

And tried this too:

let player: Player = nanoserde::DeBin::deserialize_bin(
  &hyper::body::to_bytes(api_call.into_body()).await.unwrap(),
).unwrap();

but this doesn't work, error:

thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Bin deserialize error at:8 wanted:1 bytes but max size is 1161', src\cli.rs:85:10

What does this mean?

Is there a way to fix this?

Instead of

use serde::Deserialize;

#[derive(Deserialize, Clone)]
pub struct Player {
    pub team: Team,
}
...

you need to use the appropriate nanoserde type. Something like

use nanoserde::{DeBin, SerBin};

#[derive(DeBin, SerBin, Clone)]
pub struct Player {
   pub team: Team,
}
...

Thank you. Of course I changed it. but the problem is still there.

This exact scenario (deserialization of nested structs) is tested extensively already, so I'm not sure how to help with this beyond what I suggested before. You might consider binding the hyper::body::to_bytes(api_call.into_body()).await.unwrap() to a temporary variable to confirm the values look ok, but without a repro I can run there's not much else I can do here. Hope you've been able to solve this.

On second thought, after reading through it again, it looks the endpoint may still have been giving json, and you've attempted to deserialize it as binary.

use nanoserde::{DeJson};

#[derive(DeJson, Clone)]
pub struct Player {
   pub team: Team,
}

with

match nanoserde::DeJson::deserialize_json::<Player>(
   &hyper::body::to_bytes(api_call.into_body()).await.unwrap(),
) {
  // ...
}

might give you what you needed.