// CRATES use actix_web::{get, web, HttpResponse, Result}; use askama::Template; use comrak::{markdown_to_html, ComrakOptions}; use chrono::{TimeZone, Utc}; // STRUCTS #[derive(Template)] #[template(path = "post.html", escape = "none")] struct PostTemplate { comments: Vec, post: Post, sort: String } pub struct Post { pub title: String, pub community: String, pub body: String, pub author: String, pub url: String, pub score: String, pub media: String, pub time: String } pub struct Comment { pub body: String, pub author: String, pub score: String, pub time: String } async fn render(id: String, sort: String) -> Result { println!("id: {}", id); let post: Post = fetch_post(&id).await; let comments: Vec = fetch_comments(id, &sort).await.unwrap(); let s = PostTemplate { comments: comments, post: post, sort: sort } .render() .unwrap(); // println!("{}", s); 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)>) -> Result { render(id.to_string(), "confidence".to_string()).await } #[get("/r/{sub}/comments/{id}/{title}/{sort}")] async fn sorted(web::Path((_sub, id, _title, sort)): web::Path<(String, String, String, String)>) -> Result { render(id.to_string(), sort).await } // UTILITIES async fn val (j: &serde_json::Value, k: &str) -> String { String::from(j["data"][k].as_str().unwrap_or("")) } 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#"