Search code examples
jsonrustserdeserde-json

Panic while deserializing JSON data


I'm currently trying to use some API keys to access the Kucoin exchange from my program.I want to be able to have a global initialization of the keys so I can reuse them as credentials in different functions and modules.

I store the keys in a credentials.json file that looks like this:

[{
  "name": "",
  "api_key": "",
  "api_secret": "",
  "api_pass": ""
}, {
  "name": "",
  "api_key": "",
  "api_secret": "",
  "api_pass": ""
}]

And then go ahead and try to deserialize the json into a format that I can use with my functions, like so:

use kucoin_rs::{serde_json, serde_derive::{Serialize, Deserialize}};

static  CREDENTIALS_JSON: &'static str = include_str!("./credentials.json");

#[derive(Serialize, Deserialize, Clone)]
pub struct ApiCredentials {
    pub(crate) name: String,
    pub(crate) api_key: String,
    pub(crate) api_secret: String,
    pub(crate) api_pass: String,
}

pub fn load_api_credentials() -> ApiCredentials {
  
    let deserialize_creds = serde_json::from_str::<ApiCredentials(&CREDENTIALS_JSON).expect("Error deserializing JSON data");
    deserialize_creds
    
}

The code compiles when I run cargo check, but panics when I cargo run.The error message reads

thread 'main' panicked at 'Error deserializing JSON data: Error("invalid type: map, expected a string", line: 1, column: 1)'

The message says that it expects a string, so I try to parse CREDENTIALS_JSON as string like so:

 let deserialize_creds = serde_json::from_str::<ApiCredentials>(&CREDENTIALS_JSON.to_string()).expect("Unable to deserialize credentials.json!");

But I still get the same error, what I'm I doing wrong?


Solution

  • Your json is a list of credentials. Deserialize it into a Vec like this:

    pub fn load_api_credentials() -> Vec<ApiCredentials> {
        let deserialize_creds = serde_json::from_str::<Vec<ApiCredentials>>(&CREDENTIALS_JSON).expect("Error deserializing JSON data");
        deserialize_creds
    }
    

    Or return the first one:

    pub fn load_api_credentials() -> ApiCredentials {
        let mut deserialize_creds = serde_json::from_str::<Vec<ApiCredentials>>(&CREDENTIALS_JSON).expect("Error deserializing JSON data");
        deserialize_creds.swap_remove(0)
    }