use axum::{extract::Query, Json}; use reqwest::Response; use serde::Deserialize; use serde_json::{from_str, json, Value}; use std::collections::HashMap; pub async fn search(params: Params) -> Result { let client = reqwest::Client::builder() .user_agent("JustLearningRust/1.0") .build()?; let mut query = String::new(); if let Some(q) = params.q { query.push_str(&format!("&q={}", q)); } if let Some(latitude) = params.latitude { query.push_str(&format!("&lat={}", latitude)); } if let Some(longitude) = params.longitude { query.push_str(&format!("&lon={}", longitude)); } let url = format!( "https://nominatim.openstreetmap.org/search?format=json{}", query ); let res = client.get(url).send().await?; Ok(res) } #[derive(Deserialize)] pub struct Params { q: Option, latitude: Option, longitude: Option, } pub async fn search_handler(Query(params): Query) -> Json { let res = search(params).await.expect("Failed to get response body"); let str = &res.text().await.expect("Failed to get response body"); let json: Vec> = from_str(str).unwrap(); let mut ret = Vec::new(); for el in json.iter() { let display_name = el.get("display_name").unwrap().as_str().unwrap(); if display_name.contains("United States") || display_name.contains("Canada") || display_name.contains("Brasil") // there's no way to filter by population { ret.push(json!({"name": el.get("display_name"), "latitude": el.get("lat"), "longitude": el.get("lon"), "score": el.get("importance")})); } } Json(json!({ "suggestions": ret })) }