@@ -2,14 +2,17 @@ use std::sync::LazyLock;
22
33use axum:: {
44 extract:: { Path , State } ,
5- http:: StatusCode ,
5+ http:: { header, StatusCode } ,
6+ response:: IntoResponse ,
67 Json ,
78} ;
89use futures:: TryStreamExt ;
10+ use geojson:: { feature:: Id , Feature , FeatureCollection , JsonObject } ;
911use mongodb:: {
1012 bson:: { doc, Uuid } ,
1113 Database ,
1214} ;
15+ use serde_json:: Value ;
1316
1417use crate :: models:: ChangingRoom ;
1518
@@ -42,6 +45,73 @@ pub async fn get_all_rooms(
4245 Ok ( Json ( rooms) )
4346}
4447
48+ pub async fn get_all_rooms_v2 (
49+ State ( db) : State < Database > ,
50+ ) -> Result < impl IntoResponse , ( StatusCode , String ) > {
51+ let collection = db. collection :: < ChangingRoom > ( "rooms" ) ;
52+
53+ let rooms: Vec < ChangingRoom > = collection
54+ . find ( doc ! { } )
55+ . await
56+ . map_err ( |e| {
57+ tracing:: error!( err = e. to_string( ) , "Unable to get cursor for all rooms" ) ;
58+ GENERIC_DB_ERROR . clone ( )
59+ } ) ?
60+ . try_collect ( )
61+ . await
62+ . map_err ( |e| {
63+ tracing:: error!( err = e. to_string( ) , "Unable to collect rooms into Vec" ) ;
64+ GENERIC_DB_ERROR . clone ( )
65+ } ) ?;
66+
67+ let rooms_geo = rooms
68+ . into_iter ( )
69+ . filter_map ( |r| {
70+ // ^ Replace with ord map when data migr complete
71+
72+ // Properties
73+ let mut props = JsonObject :: new ( ) ;
74+ props. insert ( String :: from ( "name" ) , Value :: String ( r. name ) ) ;
75+ props. insert (
76+ String :: from ( "ratings" ) ,
77+ serde_json:: to_value ( r. ratings )
78+ . inspect_err ( |e| {
79+ tracing:: error!(
80+ err = e. to_string( ) ,
81+ room_id = r. id. to_string( ) ,
82+ "Unable to serialize rating"
83+ ) ;
84+ } )
85+ . unwrap ( ) ,
86+ ) ;
87+ if let Some ( ext_id) = r. external_id {
88+ props. insert ( String :: from ( "externalId" ) , Value :: String ( ext_id) ) ;
89+ } else {
90+ props. insert ( String :: from ( "externalId" ) , Value :: Null ) ;
91+ }
92+
93+ // Geo Feature
94+ r. location_geo . map ( |geo| Feature {
95+ bbox : None ,
96+ geometry : Some ( geo) ,
97+ id : Some ( Id :: String ( r. id . to_string ( ) ) ) ,
98+ properties : Some ( props) ,
99+ foreign_members : None ,
100+ } )
101+ } )
102+ . collect :: < Vec < _ > > ( ) ;
103+
104+ Ok ( (
105+ StatusCode :: OK ,
106+ [ ( header:: CONTENT_TYPE , "application/geo+json" ) ] ,
107+ Json ( FeatureCollection {
108+ bbox : None ,
109+ features : rooms_geo,
110+ foreign_members : None ,
111+ } ) ,
112+ ) )
113+ }
114+
45115pub async fn get_room_by_id (
46116 Path ( id) : Path < String > ,
47117 State ( db) : State < Database > ,
@@ -64,7 +134,7 @@ pub async fn get_room_by_id(
64134 Some ( room) => Ok ( Json ( room) ) ,
65135 None => Err ( (
66136 StatusCode :: NOT_FOUND ,
67- format ! ( "No room found with id {:?}" , id ) ,
137+ format ! ( "No room found with id {id :?}" ) ,
68138 ) ) ,
69139 }
70140}
0 commit comments