Parsing JSON response to just... JSON?

Hello. I am making a GET request to the star wars api using reqwest blocking.

When I get my response, all I want to do is parse the JSON and print it to the terminal. I don't know the form of the data, and I don't think I should need to know the form of the data, right? I am struggling with understanding what I can do to get rid of the slashes and just "pretty print" the JSON. I've ended up using the Value Struct that is provided by serde_json, but I end up with this:

Object({
    "characters": Array([
        String(
            "http://swapi.dev/api/people/1/",
        ),
        String(
            "http://swapi.dev/api/people/2/",
        ),
etc....

This seems a little noisy. Maybe I am being too picky :sweat_smile:

The response, before I parse it to the Value struct is:

"{\"name\":\"R2-D2\",\"height\":\"96\",\"mass\":\"32\",\"hair_color\":\"n/a\",\"skin_color\":\"white, blue\",\"eye_color\":\"red\",\"birth_year\":\"33BBY\",\"gender\":\"n/a\",\"homeworld\":\"http://swapi.dev/api/planets/8/\",\"films\":[\"http://swapi.dev/api/films/1/\",\"http://swapi.dev/api/films/2/\",\"http://swapi.dev/api/films/3/\",\"http://swapi.dev/api/films/4/\",\"http://swapi.dev/api/films/5/\",\"http://swapi.dev/api/films/6/\"],\"species\":[\"http://swapi.dev/api/species/2/\"],\"vehicles\":[],\"starships\":[],\"created\":\"2014-12-10T15:11:50.376000Z\",\"edited\":\"2014-12-20T21:17:50.311000Z\",\"url\":\"http://swapi.dev/api/people/3/\"}"

Full code is:

fn main() -> Result<(), Error> {
    let args = Cli::from_args();

    let url = format!("http://swapi.dev/api/{}/{}", args.attributes, args.id);

    let pb = ProgressBar::new_spinner();
    pb.enable_steady_tick(120);
    pb.set_style(
        ProgressStyle::default_spinner()
            .tick_strings(&["πŸŒ‘ ", "πŸŒ’ ", "πŸŒ“ ", "πŸŒ” ", "πŸŒ• ", "πŸŒ– ", "πŸŒ— ", "🌘 "])
            .template("{spinner:.blue} {msg}"),
    );

    let request = reqwest::blocking::get(&url)?;

    match request.status() {
        StatusCode::NOT_FOUND => {
            pb.finish_with_message("Received a 404. Please try swcli --help");
        }
        StatusCode::OK => {
            pb.finish_with_message("Found!");
            let body: Value = request.json()?;
            println!("{:#?}", body)
        }
        _ => {
            pb.finish_with_message("Something went wrong");
            println!("Status Code: {}", request.status());
        }
    };
    Ok(())
}

Thank you.

Try removing the question mark

println!("{:#}", body)
1 Like

Bam.

That did it.

Thank you!

So, I did need to parse the "unknown" JSON into the Value struct? Is that the idiomatic way of accepting unknown structured JSON in Rust?

{
  "birth_year": "52BBY",
  "created": "2014-12-10T15:52:14.024000Z",
  "edited": "2014-12-20T21:17:50.317000Z",
  "eye_color": "blue",
  "films": [
    "http://swapi.dev/api/films/1/",
    "http://swapi.dev/api/films/5/",
    "http://swapi.dev/api/films/6/"
  ],
  "gender": "male",
  "hair_color": "brown, grey",
  "height": "178",
  "homeworld": "http://swapi.dev/api/planets/1/",
  "mass": "120",
  "name": "Owen Lars",
  "skin_color": "light",
  "species": [],
  "starships": [],
  "url": "http://swapi.dev/api/people/6/",
  "vehicles": []
}

Yea that seems like a fine use of Value. You’re basically just validating that it’s proper json if you don’t actually read any of the results.

As far as why the previous fix worked is that with the question mark you are using the Debug trait but without the question mark it uses the Display trait. The documentation for Value describes the differences in output.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.