Lines
23.91 %
Functions
5.71 %
Branches
100 %
use std::sync::Arc;
use askama::Template;
use axum::{
Extension, Json,
extract::State,
http::{HeaderMap, StatusCode, header},
response::IntoResponse,
};
use serde::Serialize;
use server::command::{CmdResult, FinanceEntity, commodity::ListCommodities};
use sqlx::types::Uuid;
use crate::{AppState, jwt_auth::JWTAuthMiddleware, pages::HtmlTemplate};
#[derive(Template)]
#[template(path = "pages/commodity/list.html")]
struct CommodityListPage;
pub async fn commodity_list_page() -> impl IntoResponse {
let template = CommodityListPage {};
HtmlTemplate(template)
}
struct CommodityView {
id: Uuid,
symbol: String,
name: String,
#[derive(Serialize)]
struct CommodityJson {
id: String,
#[template(path = "components/commodity/table.html")]
struct CommodityTableTemplate {
commodities: Vec<CommodityView>,
pub async fn commodity_table(
State(_data): State<Arc<AppState>>,
Extension(jwt_auth): Extension<JWTAuthMiddleware>,
headers: HeaderMap,
) -> Result<impl IntoResponse, StatusCode> {
let result = ListCommodities::new()
.user_id(jwt_auth.user.id)
.run()
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let mut commodities = Vec::new();
if let Some(CmdResult::TaggedEntities { entities, .. }) = result {
for (entity, tags) in entities {
if let FinanceEntity::Commodity(commodity) = entity {
// Find symbol and name tags
let (symbol, name) = if let (FinanceEntity::Tag(s), FinanceEntity::Tag(n)) =
(&tags["symbol"], &tags["name"])
{
(s.tag_value.clone(), n.tag_value.clone())
} else {
return Err(StatusCode::INTERNAL_SERVER_ERROR);
commodities.push(CommodityView {
id: commodity.id,
symbol,
name,
});
let wants_json = headers
.get(header::ACCEPT)
.and_then(|value| value.to_str().ok())
.is_some_and(|value| value.contains("application/json"));
if wants_json {
let commodities_json: Vec<CommodityJson> = commodities
.iter()
.map(|c| CommodityJson {
id: c.id.to_string(),
symbol: c.symbol.clone(),
name: c.name.clone(),
})
.collect();
return Ok(Json(commodities_json).into_response());
Ok(HtmlTemplate(CommodityTableTemplate { commodities }).into_response())