use actix_web::{post, web::Json, HttpResponse}; use serde::{Deserialize, Serialize}; use std::time::{SystemTime, UNIX_EPOCH}; use uuid::Uuid; #[derive(Deserialize, Debug)] pub struct PostPdfRequest { pub html: String, } #[derive(Serialize)] pub struct PostPdfResponse { pub error: Option, pub filename: Option, } #[post("/v1/pdf")] async fn post_pdf(data: Json) -> HttpResponse { let pdf_app = match wkhtmltopdf::PdfApplication::new() { Ok(x) => x, Err(x) => { return HttpResponse::InternalServerError().json(PostPdfResponse { error: Some(x.to_string()), filename: None, }) } }; let mut pdfout = match pdf_app .builder() .orientation(wkhtmltopdf::Orientation::Portrait) .margin(wkhtmltopdf::Size::Millimeters(10)) .build_from_html(&data.html) { Ok(x) => x, Err(x) => { return HttpResponse::InternalServerError().json(PostPdfResponse { error: Some(x.to_string()), filename: None, }) } }; let start = SystemTime::now(); let since_epoch = start .duration_since(UNIX_EPOCH) .expect("Time went backwards"); let filename = format!("/static/{}_{}.pdf", since_epoch.as_secs(), Uuid::new_v4()); if let Err(x) = pdfout.save(&filename) { return HttpResponse::InternalServerError().json(PostPdfResponse { error: Some(x.to_string()), filename: None, }); } HttpResponse::Created().json(PostPdfResponse { error: None, filename: Some(filename), }) }