Lines
22.22 %
Functions
20 %
Branches
100 %
use axum::http::StatusCode;
use axum::{Extension, Json, extract::State};
use serde::{Deserialize, Serialize};
use server::command::{CmdResult, FinanceEntity, commodity::ListCommodities};
use std::sync::Arc;
use crate::{AppState, jwt_auth::JWTAuthMiddleware};
#[derive(Deserialize)]
pub struct CommoditySearch {
#[serde(rename = "commodity-search")]
query: Option<String>,
}
#[derive(Serialize)]
pub struct CommodityJson {
id: String,
symbol: String,
name: String,
pub async fn search_commodities(
State(_data): State<Arc<AppState>>,
Extension(jwt_auth): Extension<JWTAuthMiddleware>,
Json(form): Json<CommoditySearch>,
) -> Result<Json<Vec<CommodityJson>>, StatusCode> {
let result = match ListCommodities::new().user_id(jwt_auth.user.id).run().await {
Ok(Some(CmdResult::TaggedEntities { entities, .. })) => entities,
_ => return Ok(Json(vec![])),
};
let mut commodities = Vec::new();
for (entity, tags) in result {
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 {
continue;
// Filter by search query if provided
if let Some(query) = &form.query {
if query.is_empty()
|| symbol.to_lowercase().contains(&query.to_lowercase())
|| name.to_lowercase().contains(&query.to_lowercase())
commodities.push(CommodityJson {
id: commodity.id.to_string(),
symbol,
name,
});
Ok(Json(commodities))