-1

I'm coding a basic video streaming website, and am having trouble parsing json into rust. When I attempt to access the page 'http://127.0.0.1:8000/genres' I get a 500 response and in the console it says


GET /genres text/html:
   >> Matched: (genres) GET /genres
thread 'rocket-worker-thread' panicked at 'called `Option::unwrap()` on a `None` value', src\main.rs:25:44
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
   >> Handler genres panicked.

My code is:

#[macro_use] extern crate rocket;
extern crate reqwest;
extern crate serde;
extern crate serde_json;

use rocket::*;
use serde::{Deserialize, Serialize};
use serde_json::{Value};

#[derive(Serialize, Deserialize, Debug)]
struct Genre {
    genre: String
}

#[get("/genres")]
async fn genres() -> String {
    let response = match reqwest::get("http://34.88.173.79/myflix/genres").await {
        Ok(response) => response,
        Err(e) => return format!("Error: {}", e),
    };
    
    let json_string = response.text().await.unwrap();
    let json: Value = serde_json::from_str(&json_string).unwrap();

    let genres = json["genres"].as_array().unwrap();
    let mut html = String::new();
    for genre in genres {
        html.push_str(&format!("<h1>{}</h1>", genre));
    }
    html
}

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

#[launch]
fn rocket() -> _ {
    rocket::build().mount("/", routes![index, genres])
}

and my cargo.toml is:

[package]
name = "dev_ops_webapp"
version = "0.1.0"
edition = "2021"

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

[dependencies]
rocket = "0.5.0-rc.2"
reqwest = "0.11.13"
serde = "1.0.151"
serde_json = "1.0.90"
futures = "0.3"
tokio = { version = "1.12.0", features = ["full"] }

I know that it's probably not the best solution but I just can't figure it out! Any help given will be amazing.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
prorex
  • 3
  • 2
  • You are trying to retrieve the value `response["genre"]`, but if I go to the website where you retrieve the JSON data, I don't get an object, but an array of objects which have the `genre` key. So maybe you should iterate over that array beforehand? – jthulhu Dec 18 '22 at 18:12
  • Please reduce your problem into a [minimal reproducible example](/help/minimal-reproducible-example). The fact that the error occurs in a Rocket handler is unrelated and should be removed from your question. You should also investigate which `.unwrap()` is the culprit (it appears to be `json["genres"].as_array().unwrap()`), that will give you a better understanding of what is wrong. And as part of the minimal reproducible example, please provide the data you are trying to parse, since the fact that it can from via `reqwest` also appears unrelated as well. – kmdreko Dec 18 '22 at 18:13
  • @cafce25 Please do not modify or add crucial data to posts unless provided by the OP. There are many reasons why that could be incorrect. I also encourage you to not fetch and post data from random unverified sites for many other reasons. – kmdreko Dec 18 '22 at 18:22

1 Answers1

-1

You misread the format of the response. You're getting an array of objects which have a "genre" key. Not an object which has a "genres" key with an array of strings.

You can replace your parsing with this:

let json: Value = serde_json::from_str(&json_string).unwrap();

for genre in json.as_array().unwrap() {
    html.push_str(&format!("<h1>{}</h1>", genre.as_str().unwrap()));
}
cafce25
  • 15,907
  • 4
  • 25
  • 31
  • This has been very helpful, thanks. Upon running it still has the same error, but about the 'genre.as_str().unwrap()'. I changed it to just 'html.push_str(&format!("

    {}

    ", genre));' and I finally get some result out!
    – prorex Dec 18 '22 at 18:39