accounters/webserver/src/main.rs

127 lines
3.9 KiB
Rust
Raw Normal View History

2024-02-12 14:04:03 +01:00
use std::net::SocketAddr;
use std::sync::Arc;
use sqlx::SqlitePool;
use axum::{
extract::FromRef,
routing::{get, post},
Router,
};
use hyper::StatusCode;
2024-02-19 23:51:18 +01:00
use tera::Tera;
2024-02-12 14:04:03 +01:00
mod routes;
mod users;
const DB_URL: &str = "sqlite://sqlite.db";
#[tokio::main]
async fn main() {
let db = accounters::create_db(DB_URL).await.unwrap();
2024-02-19 23:51:18 +01:00
let mut tmpls = Tera::new("templates/*").unwrap();
tmpls.autoescape_on(vec!["html"]);
let state = AppState {
db: Arc::new(db),
tmpls: Arc::new(tmpls),
};
2024-02-12 14:04:03 +01:00
let app = Router::new()
2024-02-19 23:51:18 +01:00
.nest(
"/",
Router::new()
.route("/", get(routes::ui::index))
.route("/accounts/id/:id", get(routes::ui::account::list))
.route(
"/accounts/id/:id/transactions/add",
get(routes::ui::account::add_transactions_view),
)
.route(
"/accounts/id/:id/transactions/add",
post(routes::ui::account::add_transactions_action),
)
2024-03-20 20:49:22 +01:00
.route(
"/classifiers",
get(routes::ui::classifier::view_classifiers),
)
.route(
"/classifiers/new_rule",
get(routes::ui::classifier::rules_new_view),
)
.route(
"/classifiers/new_rule",
post(routes::ui::classifier::rules_new_action),
)
.route(
"/classifiers/new_category",
get(routes::ui::classifier::category_new_view),
)
.route(
"/classifiers/new_category",
post(routes::ui::classifier::category_new_action),
)
2024-02-19 23:51:18 +01:00
.nest(
"/static",
Router::new()
.route("/styles.css", get(routes::static_routes::styles))
.route("/csv.js", get(routes::static_routes::csv)),
2024-02-19 23:51:18 +01:00
),
)
2024-02-12 14:04:03 +01:00
.nest(
"/api/v1",
Router::new()
2024-02-19 23:51:18 +01:00
.route("/user", post(routes::api::create_user))
.route("/login", post(routes::api::login))
.route("/accounts", post(routes::api::accounts::account_create))
.route("/accounts", get(routes::api::accounts::account_list))
.route("/accounts/id/:id", get(routes::api::accounts::account_get))
2024-02-12 14:04:03 +01:00
.route(
"/accounts/id/:id/transaction",
2024-02-19 23:51:18 +01:00
post(routes::api::transactions::create),
2024-02-12 14:04:03 +01:00
)
.route(
"/accounts/id/:id/transaction",
2024-02-19 23:51:18 +01:00
get(routes::api::transactions::list),
2024-02-12 14:04:03 +01:00
)
.route(
"/accounts/id/:id/recategorize",
2024-02-19 23:51:18 +01:00
post(routes::api::accounts::recategorize),
2024-02-12 14:04:03 +01:00
)
2024-02-19 23:51:18 +01:00
.route("/categories", post(routes::api::categories::create))
.route("/categories", get(routes::api::categories::list))
.route("/rules", post(routes::api::rules::create))
.route("/rules", get(routes::api::rules::list)),
2024-02-12 14:04:03 +01:00
)
.with_state(state);
let addr = SocketAddr::from(([0, 0, 0, 0], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
#[derive(Clone)]
pub struct AppState {
db: Arc<SqlitePool>,
2024-02-19 23:51:18 +01:00
tmpls: Arc<Tera>,
2024-02-12 14:04:03 +01:00
}
impl FromRef<AppState> for Arc<SqlitePool> {
fn from_ref(state: &AppState) -> Arc<SqlitePool> {
state.db.clone()
}
}
2024-02-19 23:51:18 +01:00
impl FromRef<AppState> for Arc<Tera> {
fn from_ref(state: &AppState) -> Arc<Tera> {
state.tmpls.clone()
}
}
2024-02-12 14:04:03 +01:00
async fn index() -> (StatusCode, String) {
(StatusCode::OK, String::from("Hello, World!"))
}