comments/src/main.rs

106 lines
2.8 KiB
Rust

use rocket::response::content;
use sqlx::SqlitePool;
use std::env;
struct Comment {
id: i64,
name: Option<String>,
content: String,
}
async fn get_comments(pool: &SqlitePool, page: &str) -> Result<Vec<Comment>, sqlx::Error> {
let results = sqlx::query!(
"SELECT id, name, content FROM comments WHERE page = ?",
page
)
.fetch_all(pool)
.await?
.into_iter()
.map(|result| Comment {
id: result.id,
name: result.name,
content: result.content,
})
.collect();
return Ok(results);
}
#[rocket::get("/txt?<page>")]
async fn txt(page: &str, pool: &rocket::State<SqlitePool>) -> Result<String, String> {
Ok(get_comments(pool, page)
.await
.map_err(|_| "error fetching comments for this page, sorry")?
.into_iter()
.map(|rec| {
format!(
"- [{}] {}: {}\n",
rec.id,
rec.name.unwrap_or("anonymous".to_owned()),
rec.content,
)
})
.collect::<String>())
}
#[rocket::get("/html?<page>")]
async fn html(
page: &str,
pool: &rocket::State<SqlitePool>,
) -> Result<content::RawHtml<String>, String> {
let comments = get_comments(pool, page)
.await
.map_err(|_| "error fetching comments for this page, sorry")?;
let html = format!(
r#"<div class="comments">{}</div>"#,
comments
.into_iter()
.map(|rec| {
format!(
r#"
<div class="comment" data-id="{}">
<div class="comment__author">{}</div>
<div class="comment__content">{}</div>
</div>
"#,
rec.id,
html_escape::encode_text(&rec.name.unwrap_or("anonymous".to_owned())),
html_escape::encode_text(&rec.content),
)
})
.collect::<String>()
);
Ok(content::RawHtml(html))
}
#[rocket::get("/add?<page>&<name>&<content>")]
async fn add(
page: &str,
name: Option<&str>,
content: &str,
pool: &rocket::State<SqlitePool>,
) -> Result<(), String> {
sqlx::query!(
"INSERT INTO comments (page, name, content) VALUES (?, ?, ?)",
page,
name,
content
)
.execute(pool.inner())
.await
.map_err(|_| "ajkl;shfklshadflgksdfg")?;
Ok(())
}
#[rocket::launch]
async fn rocket() -> _ {
let db_url = env::var("DATABASE_URL").expect("DATABASE_URL is required");
let pool = SqlitePool::connect(&db_url)
.await
.expect("Failed to connect to database");
rocket::build()
.manage(pool)
.mount("/", rocket::routes![txt, html, add])
}