2025-10-18 20:54:23 +02:00
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
|
|
|
|
use axum::{extract::State, response::Html, routing::get, Router};
|
|
|
|
|
use rusqlite::Connection;
|
|
|
|
|
use askama::Template;
|
|
|
|
|
|
|
|
|
|
#[derive(Template)]
|
|
|
|
|
#[template(path = "index.html")]
|
|
|
|
|
struct IndexTemplate {
|
|
|
|
|
tasks: Vec<Task>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
|
|
|
struct Task {
|
|
|
|
|
id: i32,
|
|
|
|
|
name: String,
|
|
|
|
|
worth: f32,
|
|
|
|
|
times_completed: i32,
|
|
|
|
|
}
|
2025-10-18 20:50:04 +02:00
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() {
|
2025-10-18 20:54:23 +02:00
|
|
|
let db_connecion_str = "./tasks.db".to_string();
|
|
|
|
|
let conn = Connection::open(db_connecion_str).unwrap();
|
|
|
|
|
conn.execute(include_str!("create_tables.sql"), ()).unwrap();
|
|
|
|
|
let conn = Arc::new(Mutex::new(conn));
|
|
|
|
|
|
|
|
|
|
let app = Router::new().route("/", get(root)).with_state(conn);
|
2025-10-18 20:50:04 +02:00
|
|
|
|
|
|
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3001").await.unwrap();
|
|
|
|
|
println!("listening on {}", listener.local_addr().unwrap());
|
|
|
|
|
axum::serve(listener, app).await.unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-18 20:54:23 +02:00
|
|
|
async fn root(
|
|
|
|
|
State(conn): State<Arc<Mutex<Connection>>>
|
|
|
|
|
) -> Html<String> {
|
|
|
|
|
let conn = conn.lock().unwrap();
|
|
|
|
|
let mut stmt = conn.prepare("SELECT id, name, worth, times_completed FROM task").unwrap();
|
|
|
|
|
let tasks = stmt.query_map((), |row| {
|
|
|
|
|
Ok(Task {
|
|
|
|
|
id: row.get(0).unwrap(),
|
|
|
|
|
name: row.get(1).unwrap(),
|
|
|
|
|
worth: row.get(2).unwrap(),
|
|
|
|
|
times_completed: row.get(3).unwrap(),
|
|
|
|
|
})
|
|
|
|
|
}).unwrap().collect::<Result<_, _>>().unwrap();
|
|
|
|
|
let index = IndexTemplate {tasks};
|
|
|
|
|
Html(
|
|
|
|
|
index.render().unwrap()
|
|
|
|
|
)
|
2025-10-18 20:49:21 +02:00
|
|
|
}
|