1- use crate :: { objects:: * , Error , RawGtfs } ;
1+ use crate :: { objects:: * , Error , Id , RawGtfs } ;
22use chrono:: prelude:: NaiveDate ;
33use chrono:: Duration ;
44use std:: collections:: { HashMap , HashSet } ;
55use std:: convert:: TryFrom ;
6- use std:: sync:: Arc ;
76
87/// Data structure with all the GTFS objects
98///
@@ -27,8 +26,8 @@ pub struct Gtfs {
2726 pub calendar : HashMap < String , Calendar > ,
2827 /// All calendar dates grouped by service_id
2928 pub calendar_dates : HashMap < String , Vec < CalendarDate > > ,
30- /// All stop by `stop_id`. Stops are in an [Arc] because they are also referenced by each [StopTime]
31- pub stops : HashMap < String , Arc < Stop > > ,
29+ /// All stop by `stop_id`
30+ pub stops : HashMap < Id < Stop > , Stop > ,
3231 /// All routes by `route_id`
3332 pub routes : HashMap < String , Route > ,
3433 /// All trips by `trip_id`
@@ -49,12 +48,12 @@ impl TryFrom<RawGtfs> for Gtfs {
4948 ///
5049 /// It might fail if some mandatory files couldn’t be read or if there are references to other objects that are invalid.
5150 fn try_from ( raw : RawGtfs ) -> Result < Gtfs , Error > {
51+ let frequencies = raw. frequencies . unwrap_or_else ( || Ok ( Vec :: new ( ) ) ) ?;
5252 let stops = to_stop_map (
5353 raw. stops ?,
5454 raw. transfers . unwrap_or_else ( || Ok ( Vec :: new ( ) ) ) ?,
5555 raw. pathways . unwrap_or ( Ok ( Vec :: new ( ) ) ) ?,
5656 ) ?;
57- let frequencies = raw. frequencies . unwrap_or_else ( || Ok ( Vec :: new ( ) ) ) ?;
5857 let trips = create_trips ( raw. trips ?, raw. stop_times ?, frequencies, & stops) ?;
5958
6059 Ok ( Gtfs {
@@ -175,10 +174,10 @@ impl Gtfs {
175174 }
176175
177176 /// Gets a [Stop] by its `stop_id`
178- pub fn get_stop < ' a > ( & ' a self , id : & str ) -> Result < & ' a Stop , Error > {
177+ pub fn get_stop < ' a > ( & ' a self , id : & Id < Stop > ) -> Result < & ' a Stop , Error > {
179178 match self . stops . get ( id) {
180179 Some ( stop) => Ok ( stop) ,
181- None => Err ( Error :: ReferenceError ( id. to_owned ( ) ) ) ,
180+ None => Err ( Error :: ReferenceError ( id. to_string ( ) ) ) ,
182181 }
183182 }
184183
@@ -225,7 +224,7 @@ impl Gtfs {
225224 }
226225}
227226
228- fn to_map < O : Id > ( elements : impl IntoIterator < Item = O > ) -> HashMap < String , O > {
227+ fn to_map < O : WithId > ( elements : impl IntoIterator < Item = O > ) -> HashMap < String , O > {
229228 elements
230229 . into_iter ( )
231230 . map ( |e| ( e. id ( ) . to_owned ( ) , e) )
@@ -236,33 +235,35 @@ fn to_stop_map(
236235 stops : Vec < Stop > ,
237236 raw_transfers : Vec < RawTransfer > ,
238237 raw_pathways : Vec < RawPathway > ,
239- ) -> Result < HashMap < String , Arc < Stop > > , Error > {
240- let mut stop_map: HashMap < String , Stop > =
241- stops. into_iter ( ) . map ( |s| ( s. id . clone ( ) , s) ) . collect ( ) ;
242-
238+ ) -> Result < HashMap < Id < Stop > , Stop > , Error > {
239+ let mut stop_map = HashMap :: < Id < Stop > , Stop > :: default ( ) ;
240+ for s in stops. into_iter ( ) {
241+ stop_map. insert ( Id :: must_exists ( s. id . clone ( ) ) , s) ;
242+ }
243243 for transfer in raw_transfers {
244+ // Note: I'm not convinced at all by this Id::must_exists...
245+ // we shouldn't have to allocate here, and we must find a way to really ensure that the id exists (or remove the verbosity)
244246 stop_map
245- . get ( & transfer. to_stop_id )
247+ . get ( & Id :: must_exists ( transfer. to_stop_id . clone ( ) ) )
246248 . ok_or_else ( || Error :: ReferenceError ( transfer. to_stop_id . to_string ( ) ) ) ?;
247- stop_map
248- . entry ( transfer. from_stop_id . clone ( ) )
249- . and_modify ( |stop| stop. transfers . push ( StopTransfer :: from ( transfer) ) ) ;
249+ let to_stop_id = Id :: must_exists ( transfer. to_stop_id . clone ( ) ) ;
250+ let s = stop_map
251+ . get_mut ( & Id :: must_exists ( transfer. from_stop_id . clone ( ) ) )
252+ . ok_or_else ( || Error :: ReferenceError ( transfer. from_stop_id . to_string ( ) ) ) ?;
253+ s. transfers . push ( StopTransfer :: from ( ( transfer, to_stop_id) ) ) ;
250254 }
251255
252256 for pathway in raw_pathways {
253257 stop_map
254- . get ( & pathway. to_stop_id )
258+ . get ( & Id :: must_exists ( pathway. to_stop_id . clone ( ) ) )
255259 . ok_or_else ( || Error :: ReferenceError ( pathway. to_stop_id . to_string ( ) ) ) ?;
256- stop_map
257- . entry ( pathway. from_stop_id . clone ( ) )
258- . and_modify ( |stop| stop. pathways . push ( Pathway :: from ( pathway) ) ) ;
260+ let s = stop_map
261+ . get_mut ( & Id :: must_exists ( pathway. from_stop_id . clone ( ) ) )
262+ . ok_or_else ( || Error :: ReferenceError ( pathway. to_stop_id . to_string ( ) ) ) ?;
263+ let stop_id = Id :: must_exists ( pathway. to_stop_id . clone ( ) ) ;
264+ s. pathways . push ( Pathway :: from ( ( pathway, stop_id) ) ) ;
259265 }
260-
261- let res = stop_map
262- . into_iter ( )
263- . map ( |( i, s) | ( i, Arc :: new ( s) ) )
264- . collect ( ) ;
265- Ok ( res)
266+ Ok ( stop_map)
266267}
267268
268269fn to_shape_map ( shapes : Vec < Shape > ) -> HashMap < String , Vec < Shape > > {
@@ -292,7 +293,7 @@ fn create_trips(
292293 raw_trips : Vec < RawTrip > ,
293294 raw_stop_times : Vec < RawStopTime > ,
294295 raw_frequencies : Vec < RawFrequency > ,
295- stops : & HashMap < String , Arc < Stop > > ,
296+ stops : & HashMap < Id < Stop > , Stop > ,
296297) -> Result < HashMap < String , Trip > , Error > {
297298 let mut trips = to_map ( raw_trips. into_iter ( ) . map ( |rt| Trip {
298299 id : rt. id ,
@@ -312,10 +313,11 @@ fn create_trips(
312313 let trip = & mut trips
313314 . get_mut ( & s. trip_id )
314315 . ok_or_else ( || Error :: ReferenceError ( s. trip_id . to_string ( ) ) ) ?;
316+ let stop_id = Id :: must_exists ( s. stop_id . clone ( ) ) ;
315317 let stop = stops
316- . get ( & s . stop_id )
317- . ok_or_else ( || Error :: ReferenceError ( s . stop_id . to_string ( ) ) ) ?;
318- trip. stop_times . push ( StopTime :: from ( & s, Arc :: clone ( stop ) ) ) ;
318+ . get ( & stop_id)
319+ . ok_or_else ( || Error :: ReferenceError ( stop_id. to_string ( ) ) ) ?;
320+ trip. stop_times . push ( StopTime :: from ( & s, stop_id ) ) ;
319321 }
320322
321323 for trip in & mut trips. values_mut ( ) {
0 commit comments