1+ use crate :: db;
12use crate :: db:: main:: MainPool ;
23use crate :: rest:: error:: RestResult as Res ;
34use crate :: rest:: error:: { RestApiError , RestApiErrorCode } ;
@@ -7,8 +8,9 @@ use serde::{Deserialize, Serialize};
78
89#[ derive( Deserialize ) ]
910pub struct SearchArgs {
10- pub lat : f64 ,
11- pub lon : f64 ,
11+ pub lat : Option < f64 > ,
12+ pub lon : Option < f64 > ,
13+ pub r#type : Option < String > ,
1214}
1315
1416#[ derive( Serialize , Deserialize ) ]
@@ -23,29 +25,43 @@ pub struct AreaSearchResult {
2325
2426#[ get( "" ) ]
2527pub async fn get ( args : Query < SearchArgs > , pool : Data < MainPool > ) -> Res < Vec < AreaSearchResult > > {
26- let lat = args. lat ;
27- let lon = args. lon ;
28-
29- if !( -90.0 ..=90.0 ) . contains ( & lat) {
30- return Err ( RestApiError :: new (
31- RestApiErrorCode :: InvalidInput ,
32- "Latitude must be between -90 and 90" ,
33- ) ) ;
34- }
35-
36- if !( -180.0 ..=180.0 ) . contains ( & lon) {
37- return Err ( RestApiError :: new (
38- RestApiErrorCode :: InvalidInput ,
39- "Longitude must be between -180 and 180" ,
40- ) ) ;
41- }
42-
43- let areas = service:: area:: find_areas_by_lat_lon ( lat, lon, & pool)
44- . await
45- . map_err ( |_| RestApiError :: database ( ) ) ?;
28+ let type_filter = args. r#type . clone ( ) ;
29+
30+ let areas = if let ( Some ( lat) , Some ( lon) ) = ( args. lat , args. lon ) {
31+ if !( -90.0 ..=90.0 ) . contains ( & lat) {
32+ return Err ( RestApiError :: new (
33+ RestApiErrorCode :: InvalidInput ,
34+ "Latitude must be between -90 and 90" ,
35+ ) ) ;
36+ }
37+
38+ if !( -180.0 ..=180.0 ) . contains ( & lon) {
39+ return Err ( RestApiError :: new (
40+ RestApiErrorCode :: InvalidInput ,
41+ "Longitude must be between -180 and 180" ,
42+ ) ) ;
43+ }
44+
45+ service:: area:: find_areas_by_lat_lon ( lat, lon, & pool)
46+ . await
47+ . map_err ( |_| RestApiError :: database ( ) ) ?
48+ } else {
49+ db:: main:: area:: queries:: select ( None , false , None , & pool)
50+ . await
51+ . map_err ( |_| RestApiError :: database ( ) ) ?
52+ } ;
4653
4754 let results: Vec < AreaSearchResult > = areas
4855 . into_iter ( )
56+ . filter ( |area| {
57+ if let Some ( ref filter_type) = type_filter {
58+ let area_type = area. tags . get ( "type" ) . and_then ( |v| v. as_str ( ) ) . unwrap_or ( "" ) ;
59+ if area_type != filter_type {
60+ return false ;
61+ }
62+ }
63+ true
64+ } )
4965 . map ( |area| {
5066 let r#type = area. tags . get ( "type" ) . and_then ( |v| v. as_str ( ) ) . unwrap_or ( "" ) ;
5167 let singular_type = if let Some ( stripped) = r#type. strip_suffix ( "ies" ) {
0 commit comments