Refactor parts of the server

This commit is contained in:
Andras Schmelczer 2026-02-01 13:59:07 +00:00
parent ccb7c8fbd7
commit 47de4e563f
6 changed files with 369 additions and 90 deletions

View file

@ -0,0 +1,23 @@
use axum::http::StatusCode;
pub fn parse_bounds(bounds_str: &str) -> Result<(f64, f64, f64, f64), (StatusCode, String)> {
let parts: Vec<f64> = bounds_str
.split(',')
.map(|s| s.trim().parse::<f64>())
.collect::<Result<Vec<_>, _>>()
.map_err(|_| {
(
StatusCode::BAD_REQUEST,
"Invalid bounds format. Use: south,west,north,east".into(),
)
})?;
if parts.len() != 4 {
return Err((
StatusCode::BAD_REQUEST,
"Invalid bounds format. Use: south,west,north,east".into(),
));
}
Ok((parts[0], parts[1], parts[2], parts[3]))
}

View file

@ -6,8 +6,11 @@ use axum::response::Json;
use serde::{Deserialize, Serialize};
use tracing::info;
use crate::consts::MAX_POIS_PER_REQUEST;
use crate::data::POI;
use crate::state::AppState;
use crate::state::{AppState, POICategoryGroup};
use super::parse::parse_bounds;
#[derive(Deserialize)]
pub struct POIParams {
@ -30,28 +33,10 @@ pub async fn get_pois(
"bounds parameter is required".into(),
))?;
let parts: Vec<f64> = bounds_str
.split(',')
.map(|s| s.trim().parse::<f64>())
.collect::<Result<Vec<_>, _>>()
.map_err(|_| {
(
StatusCode::BAD_REQUEST,
"Invalid bounds format. Use: south,west,north,east".into(),
)
})?;
if parts.len() != 4 {
return Err((
StatusCode::BAD_REQUEST,
"Invalid bounds format. Use: south,west,north,east".into(),
));
}
let (south, west, north, east) = (parts[0], parts[1], parts[2], parts[3]);
let (south, west, north, east) = parse_bounds(&bounds_str)?;
let categories_str = params.categories.clone();
let category_filter: Option<Vec<String>> = params
let category_filter: Option<rustc_hash::FxHashSet<String>> = params
.categories
.as_deref()
.filter(|s| !s.is_empty())
@ -78,12 +63,13 @@ pub async fn get_pois(
id: state.poi_data.id[row].clone(),
name: state.poi_data.name[row].clone(),
category: state.poi_data.category[row].clone(),
group: state.poi_data.group[row].clone(),
lat: state.poi_data.lat[row],
lng: state.poi_data.lng[row],
emoji: state.poi_data.emoji[row].clone(),
})
})
.take(5000)
.take(MAX_POIS_PER_REQUEST)
.collect();
let elapsed = t0.elapsed();
@ -99,35 +85,25 @@ pub async fn get_pois(
POIsResponse { pois }
})
.await
.unwrap();
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
Ok(Json(result))
}
#[derive(Serialize)]
pub struct POICategoriesResponse {
categories: Vec<String>,
groups: Vec<POICategoryGroup>,
}
pub async fn get_poi_categories(state: Arc<AppState>) -> Json<POICategoriesResponse> {
let result = tokio::task::spawn_blocking(move || {
let mut categories: Vec<String> = state
.poi_data
.category
.iter()
.cloned()
.collect::<std::collections::HashSet<_>>()
.into_iter()
.collect();
let groups: Vec<POICategoryGroup> = state.poi_category_groups.clone();
categories.sort();
let total: usize = groups.iter().map(|g| g.categories.len()).sum();
info!(
count = total,
groups = groups.len(),
"GET /api/poi-categories"
);
info!(count = categories.len(), "GET /api/poi-categories");
POICategoriesResponse { categories }
})
.await
.unwrap();
Json(result)
Json(POICategoriesResponse { groups })
}