// CRATES use actix_web::{get, web, HttpResponse, Result}; use askama::Template; use chrono::{TimeZone, Utc}; use pulldown_cmark::{html, Options, Parser}; #[path = "utils.rs"] mod utils; use utils::{request, val, Comment, ErrorTemplate, Flair, Params, Post}; // STRUCTS #[derive(Template)] #[template(path = "post.html", escape = "none")] struct PostTemplate { comments: Vec, post: Post, sort: String, } async fn render(id: String, sort: String) -> Result { println!("id: {}", id); let post = fetch_post(&id).await; let comments = fetch_comments(id, &sort).await; if post.is_err() || comments.is_err() { let s = ErrorTemplate { message: post.err().unwrap().to_string(), } .render() .unwrap(); Ok(HttpResponse::Ok().status(actix_web::http::StatusCode::NOT_FOUND).content_type("text/html").body(s)) } else { let s = PostTemplate { comments: comments.unwrap(), post: post.unwrap(), sort: sort, } .render() .unwrap(); Ok(HttpResponse::Ok().content_type("text/html").body(s)) } } // SERVICES #[get("/{id}")] async fn short(web::Path(id): web::Path) -> Result { render(id.to_string(), "confidence".to_string()).await } #[get("/r/{sub}/comments/{id}/{title}/")] async fn page(web::Path((_sub, id)): web::Path<(String, String)>, params: web::Query) -> Result { match ¶ms.sort { Some(sort) => render(id, sort.to_string()).await, None => render(id, "confidence".to_string()).await, } } // UTILITIES async fn media(data: &serde_json::Value) -> String { let post_hint: &str = data["data"]["post_hint"].as_str().unwrap_or(""); let has_media: bool = data["data"]["media"].is_object(); let media: String = if !has_media { format!(r#"

{u}

"#, u = data["data"]["url"].as_str().unwrap()) } else { format!(r#""#, data["data"]["url"].as_str().unwrap()) }; match post_hint { "hosted:video" => format!( r#"