// 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::{Comment, Flair, Post, val}; // 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: 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 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#"