Fit Post Fetching into 1 Request

This commit is contained in:
spikecodes 2020-11-20 21:04:35 -08:00
parent cef3266186
commit f75b48fdc9

View File

@ -18,18 +18,33 @@ struct PostTemplate {
} }
async fn render(id: String, sort: String) -> Result<HttpResponse> { async fn render(id: String, sort: String) -> Result<HttpResponse> {
// Log the post ID being fetched
println!("id: {}", id); println!("id: {}", id);
let post = fetch_post(&id).await;
let comments = fetch_comments(id, &sort).await;
if post.is_err() || comments.is_err() { // Build the Reddit JSON API url
let url: String = format!("https://reddit.com/{}.json?sort={}", id, sort);
// Send a request to the url, receive JSON in response
let req = request(url).await;
// If the Reddit API returns an error, exit and send error page to user
if req.is_err() {
let s = ErrorTemplate { let s = ErrorTemplate {
message: post.err().unwrap().to_string(), message: req.err().unwrap().to_string(),
} }
.render() .render()
.unwrap(); .unwrap();
Ok(HttpResponse::Ok().status(actix_web::http::StatusCode::NOT_FOUND).content_type("text/html").body(s)) return Ok(HttpResponse::Ok().status(actix_web::http::StatusCode::NOT_FOUND).content_type("text/html").body(s));
} else { }
// Otherwise, grab the JSON output from the request
let res = req.unwrap();
// Parse the JSON into Post and Comment structs
let post = parse_post(res.clone()).await;
let comments = parse_comments(res).await;
// Use the Post and Comment structs to generate a website to show users
let s = PostTemplate { let s = PostTemplate {
comments: comments.unwrap(), comments: comments.unwrap(),
post: post.unwrap(), post: post.unwrap(),
@ -39,7 +54,6 @@ async fn render(id: String, sort: String) -> Result<HttpResponse> {
.unwrap(); .unwrap();
Ok(HttpResponse::Ok().content_type("text/html").body(s)) Ok(HttpResponse::Ok().content_type("text/html").body(s))
} }
}
// SERVICES // SERVICES
#[get("/{id}")] #[get("/{id}")]
@ -92,22 +106,8 @@ async fn markdown_to_html(md: &str) -> String {
} }
// POSTS // POSTS
async fn fetch_post(id: &String) -> Result<Post, &'static str> { async fn parse_post(json: serde_json::Value) -> Result<Post, &'static str> {
// Build the Reddit JSON API url let post_data: &serde_json::Value = &json[0]["data"]["children"][0];
let url: String = format!("https://reddit.com/{}.json", id);
// Send a request to the url, receive JSON in response
let req = request(url).await;
// If the Reddit API returns an error, exit this function
if req.is_err() {
return Err(req.err().unwrap());
}
// Otherwise, grab the JSON output from the request
let res = req.unwrap();
let post_data: &serde_json::Value = &res[0]["data"]["children"][0];
let unix_time: i64 = post_data["data"]["created_utc"].as_f64().unwrap().round() as i64; let unix_time: i64 = post_data["data"]["created_utc"].as_f64().unwrap().round() as i64;
let score = post_data["data"]["score"].as_i64().unwrap(); let score = post_data["data"]["score"].as_i64().unwrap();
@ -136,22 +136,8 @@ async fn fetch_post(id: &String) -> Result<Post, &'static str> {
} }
// COMMENTS // COMMENTS
async fn fetch_comments(id: String, sort: &String) -> Result<Vec<Comment>, &'static str> { async fn parse_comments(json: serde_json::Value) -> Result<Vec<Comment>, &'static str> {
// Build the Reddit JSON API url let comment_data = json[1]["data"]["children"].as_array().unwrap();
let url: String = format!("https://reddit.com/{}.json?sort={}", id, sort);
// Send a request to the url, receive JSON in response
let req = request(url).await;
// If the Reddit API returns an error, exit this function
if req.is_err() {
return Err(req.err().unwrap());
}
// Otherwise, grab the JSON output from the request
let res = req.unwrap();
let comment_data = res[1]["data"]["children"].as_array().unwrap();
let mut comments: Vec<Comment> = Vec::new(); let mut comments: Vec<Comment> = Vec::new();