septa_api/
types.rs

1use std::{fmt, str::FromStr};
2
3use crate::errors::Error;
4use serde::{
5    de::{self, Visitor},
6    Deserialize, Deserializer,
7};
8use strum::{Display, EnumCount, EnumIter, EnumString};
9
10#[derive(
11    Clone,
12    Debug,
13    Deserialize,
14    Display,
15    EnumString,
16    EnumCount,
17    EnumIter,
18    PartialEq,
19    Eq,
20    PartialOrd,
21    Ord,
22    Hash,
23)]
24pub enum TransportType {
25    Bus,
26    RegionalRail,
27    Nhsl,
28    Subway,
29    Trolley,
30}
31
32#[derive(
33    Clone,
34    Debug,
35    Deserialize,
36    Display,
37    EnumString,
38    EnumCount,
39    EnumIter,
40    PartialEq,
41    Eq,
42    PartialOrd,
43    Ord,
44    Hash,
45)]
46#[strum(serialize_all = "UPPERCASE")]
47pub enum ServiceType {
48    Express,
49    Local,
50
51    #[strum(default)]
52    Unknown(String),
53}
54
55#[derive(
56    Clone,
57    Debug,
58    Deserialize,
59    Display,
60    EnumString,
61    EnumCount,
62    EnumIter,
63    PartialEq,
64    Eq,
65    PartialOrd,
66    Ord,
67    Hash,
68)]
69#[strum(serialize_all = "title_case", ascii_case_insensitive)]
70pub enum RegionalRailsLine {
71    Airport,
72    ChestnutHillEast,
73    ChestnutHillWest,
74    Cynwyd,
75    FoxChase,
76
77    #[strum(serialize = "Lansdale/Doylestown")]
78    LansdaleDoylestown,
79
80    #[strum(serialize = "Media/Wawa")]
81    MediaWawa,
82
83    #[strum(serialize = "Manayunk/Norristown")]
84    ManayunkNorristown,
85
86    #[strum(serialize = "Paoli/Thorndale")]
87    PaoliThorndale,
88    Trenton,
89
90    #[strum(serialize = "Warminster")]
91    Warminster,
92
93    #[strum(serialize = "Wilmington/Newark")]
94    WilmingtonNewark,
95    WestTrenton,
96}
97
98impl RegionalRailsLine {
99    pub fn id(&self) -> &'static str {
100        match *self {
101            Self::Airport => "AIR",
102            Self::ChestnutHillEast => "CHE",
103            Self::ChestnutHillWest => "CHW",
104            Self::Cynwyd => "CYN",
105            Self::FoxChase => "FOX",
106            Self::LansdaleDoylestown => "LAN",
107            Self::MediaWawa => "MED",
108            Self::ManayunkNorristown => "NOR",
109            Self::PaoliThorndale => "PAO",
110            Self::Trenton => "TRE",
111            Self::Warminster => "WAR",
112            Self::WilmingtonNewark => "WIL",
113            Self::WestTrenton => "WTR",
114        }
115    }
116
117    pub fn stops(&self) -> Vec<RegionalRailStop> {
118        unimplemented!()
119    }
120}
121
122#[derive(
123    Clone, Debug, Display, EnumString, EnumCount, EnumIter, PartialEq, Eq, PartialOrd, Ord, Hash,
124)]
125#[strum(serialize_all = "title_case", ascii_case_insensitive)]
126pub enum RegionalRailStop {
127    // Airport Line Stops
128    #[strum(
129        serialize = "Airport Terminal E F",
130        serialize = "Airport Terminal E-F",
131        to_string = "Airport Terminal E F"
132    )]
133    AirportTerminalEF,
134    #[strum(
135        serialize = "Airport Terminal C D",
136        serialize = "Airport Terminal C-D",
137        to_string = "Airport Terminal C D"
138    )]
139    AirportTerminalCD,
140    #[strum(serialize = "Airport Terminal B")]
141    AirportTerminalB,
142    #[strum(serialize = "Airport Terminal A")]
143    AirportTerminalA,
144    Eastwick,
145
146    // Chestnut Hill East Line Stops
147    Stenton,
148    Wyndmoor,
149    Wister,
150    Gravers,
151    Germantown,
152    Sedgwick,
153    #[strum(serialize = "Chestnut Hill East", serialize = "Chestnut H East")]
154    ChestnutHillEast,
155    WashingtonLane,
156    MountAiry,
157
158    // Chestnut Hill West Line Stops
159    NorthPhiladelphia,
160    Upsal,
161    #[strum(serialize = "St. Martins")]
162    StMartins,
163    #[strum(serialize = "Chestnut Hill West", serialize = "Chestnut H West")]
164    ChestnutHillWest,
165    CheltenAvenue,
166    Carpenter,
167    RichardAllenLane,
168    Tulpehocken,
169    Highland,
170    QueenLane,
171
172    // Cynwyd Line Stops
173    Cynwyd,
174    Bala,
175    WynnefieldAvenue,
176
177    // Fox Chase Line Stops
178    FoxChase,
179    Ryers,
180    Cheltenham,
181    Lawndale,
182    Olney,
183
184    // Lansdale/Doylestown Line Stops
185    Doylestown,
186    DelawareValleyCollege,
187    NewBritain,
188    Chalfont,
189    LinkBelt,
190    Colmar,
191    Fortuna,
192    #[strum(serialize = "9th Street Lansdale")]
193    NinthStreetLansdale,
194    Lansdale,
195    Pennbrook,
196    NorthWales,
197    GwyneddValley,
198    Penllyn,
199    Ambler,
200    FortWashington,
201    Oreland,
202    NorthHills,
203    NorthBroad,
204
205    // Media/Wawa Line Stops
206    Wawa,
207    #[strum(serialize = "Elwyn", serialize = "Elwyn Station", to_string = "Elwyn")]
208    Elwyn,
209    Media,
210    #[strum(serialize = "Moylan-Rose Valley")]
211    MoylanRoseValley,
212    Wallingford,
213    Swarthmore,
214    Morton,
215    Secane,
216    Primos,
217    #[strum(serialize = "Clifton-Aldan")]
218    CliftonAldan,
219    Gladstone,
220    Lansdowne,
221    #[strum(serialize = "Fernwood-Yeadon", serialize = "Fernwood")]
222    FernwoodYeadon,
223    Angora,
224    #[strum(serialize = "49th Street")]
225    FortyNinthStreet,
226
227    // Manayunk/Norristown Line Stops
228    #[strum(
229        serialize = "Norristown - Elm Street",
230        serialize = "Norristown Elm Street",
231        to_string = "Norristown - Elm Street"
232    )]
233    NorristownElmStreet,
234    MainStreet,
235    #[strum(
236        serialize = "Norristown T.C.",
237        serialize = "Norristown",
238        serialize = "Norristown TC"
239    )]
240    NorristownTC,
241    Conshohocken,
242    SpringMill,
243    Miquon,
244    IvyRidge,
245    Manayunk,
246    Wissahickon,
247    EastFalls,
248    Allegheny,
249
250    // Paoli/Thorndale Line Stops
251    Thorndale,
252    Downingtown,
253    Whitford,
254    Exton,
255    Malvern,
256    Paoli,
257    Wayne,
258    #[strum(serialize = "St. Davids")]
259    StDavids,
260    Berwyn,
261    Devon,
262    Villanova,
263    Rosemont,
264    BrynMawr,
265    Strafford,
266    Daylesford,
267    Radnor,
268    Haverford,
269    Ardmore,
270    Wynnewood,
271    Narberth,
272    Overbrook,
273    Merion,
274
275    // Trenton Line Stops
276    Trenton,
277    Levittown,
278    Bristol,
279    Croydon,
280    Eddington,
281    CornwellsHeights,
282    Torresdale,
283    HolmesburgJct,
284    Tacony,
285    Bridesburg,
286    NorthPhiladelphiaAmtrak,
287
288    // Warminster Line Stops
289    Warminster,
290    Hatboro,
291    WillowGrove,
292    Crestmont,
293    Roslyn,
294    Ardsley,
295
296    // Wilmington/Newark Line Stops
297    Newark,
298    #[strum(serialize = "Churchman's Crossing")]
299    ChurchmansCrossing,
300    Wilmington,
301    Claymont,
302    MarcusHook,
303    HighlandAvenue,
304    Chester,
305    Eddystone,
306    CrumLynne,
307    RidleyPark,
308
309    #[strum(
310        serialize = "Prospect Park - Moore",
311        serialize = "Prospect Park Moore",
312        to_string = "Prospect Park - Moore"
313    )]
314    ProspectParkMoore,
315    Norwood,
316    Glenolden,
317    Folcroft,
318    SharonHill,
319    CurtisPark,
320    Darby,
321
322    // West Trenton Line Stops
323    WestTrenton,
324    Yardley,
325    Woodbourne,
326    Langhorne,
327    Neshaminy,
328    Trevose,
329    Somerton,
330    ForestHills,
331    Philmont,
332    Bethayres,
333    Meadowbrook,
334    Rydal,
335    Noble,
336
337    // Shared Stops
338    WayneJunction,
339    Glenside,
340    JenkintownWyncote,
341    #[strum(serialize = "Fern Rock T C")]
342    FernRockTC,
343    ElkinsPark,
344    MelrosePark,
345
346    // Shared Center City Stops
347    #[strum(
348        serialize = "30th Street Station",
349        serialize = "30th St",
350        serialize = "30th Street Gray",
351        serialize = "Gray 30th St",
352        to_string = "Gray 30th Street"
353    )]
354    Gray30thStreet,
355    SuburbanStation,
356    #[strum(serialize = "Jefferson Station", serialize = "Jefferson")]
357    JeffersonStation,
358    #[strum(serialize = "Temple U", serialize = "Temple University")]
359    TempleUniversity,
360    #[strum(
361        serialize = "Penn Medicine Station",
362        serialize = "Penn Medical Station"
363    )]
364    PennMedicineStation,
365
366    // Unknown Stop
367    #[strum(default)]
368    Unknown(String),
369}
370
371struct RegionalRailStopVisitor;
372
373impl<'de> Visitor<'de> for RegionalRailStopVisitor {
374    type Value = RegionalRailStop;
375
376    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
377        formatter.write_str("Expecting a serialized SEPTA regional rail stop name")
378    }
379
380    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
381    where
382        E: de::Error,
383    {
384        match RegionalRailStop::from_str(value) {
385            Ok(stop) => match stop {
386                RegionalRailStop::Unknown(stop_name) => Err(E::custom(format!(
387                    "Regional rail stop \"{}\" was not reconized",
388                    stop_name
389                ))),
390                _ => Ok(stop),
391            },
392            Err(e) => Err(E::custom(format!(
393                "Regional rail stop was not reconized becasue of error: {}",
394                e
395            ))),
396        }
397    }
398}
399
400impl<'de> Deserialize<'de> for RegionalRailStop {
401    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
402    where
403        D: Deserializer<'de>,
404    {
405        deserializer.deserialize_str(RegionalRailStopVisitor)
406    }
407}
408
409impl RegionalRailStop {
410    pub fn stop_id(&self) -> Result<u32, Error> {
411        match *self {
412            Self::Cynwyd => Ok(90001),
413            Self::Bala => Ok(90002),
414            Self::WynnefieldAvenue => Ok(90003),
415            Self::Gray30thStreet => Ok(90004),
416            Self::SuburbanStation => Ok(90005),
417            Self::JeffersonStation => Ok(90006),
418            Self::TempleUniversity => Ok(90007),
419            Self::NorthBroad => Ok(90008),
420            Self::WayneJunction => Ok(90009),
421            Self::Newark => Ok(90201),
422            Self::ChurchmansCrossing => Ok(90202),
423            Self::Wilmington => Ok(90203),
424            Self::Claymont => Ok(90204),
425            Self::MarcusHook => Ok(90205),
426            Self::HighlandAvenue => Ok(90206),
427            Self::Chester => Ok(90207),
428            Self::Eddystone => Ok(90208),
429            Self::CrumLynne => Ok(90209),
430            Self::RidleyPark => Ok(90210),
431            Self::ProspectParkMoore => Ok(90211),
432            Self::Norwood => Ok(90212),
433            Self::Glenolden => Ok(90213),
434            Self::Folcroft => Ok(90214),
435            Self::SharonHill => Ok(90215),
436            Self::CurtisPark => Ok(90216),
437            Self::Darby => Ok(90217),
438            Self::Allegheny => Ok(90218),
439            Self::EastFalls => Ok(90219),
440            Self::Wissahickon => Ok(90220),
441            Self::Manayunk => Ok(90221),
442            Self::IvyRidge => Ok(90222),
443            Self::Miquon => Ok(90223),
444            Self::SpringMill => Ok(90224),
445            Self::Conshohocken => Ok(90225),
446            Self::NorristownTC => Ok(90226),
447            Self::MainStreet => Ok(90227),
448            Self::NorristownElmStreet => Ok(90228),
449            Self::Wawa => Ok(90300),
450            Self::Elwyn => Ok(90301),
451            Self::Media => Ok(90302),
452            Self::MoylanRoseValley => Ok(90303),
453            Self::Wallingford => Ok(90304),
454            Self::Swarthmore => Ok(90305),
455            Self::Morton => Ok(90306),
456            Self::Secane => Ok(90307),
457            Self::Primos => Ok(90308),
458            Self::CliftonAldan => Ok(90309),
459            Self::Gladstone => Ok(90310),
460            Self::Lansdowne => Ok(90311),
461            Self::FernwoodYeadon => Ok(90312),
462            Self::Angora => Ok(90313),
463            Self::FortyNinthStreet => Ok(90314),
464            Self::Noble => Ok(90315),
465            Self::Rydal => Ok(90316),
466            Self::Meadowbrook => Ok(90317),
467            Self::Bethayres => Ok(90318),
468            Self::Philmont => Ok(90319),
469            Self::ForestHills => Ok(90320),
470            Self::Somerton => Ok(90321),
471            Self::Trevose => Ok(90322),
472            Self::Neshaminy => Ok(90323),
473            Self::Langhorne => Ok(90324),
474            Self::Woodbourne => Ok(90325),
475            Self::Yardley => Ok(90326),
476            Self::WestTrenton => Ok(90327),
477            Self::AirportTerminalEF => Ok(90401),
478            Self::AirportTerminalCD => Ok(90402),
479            Self::AirportTerminalB => Ok(90403),
480            Self::AirportTerminalA => Ok(90404),
481            Self::Eastwick => Ok(90405),
482            Self::PennMedicineStation => Ok(90406),
483            Self::FernRockTC => Ok(90407),
484            Self::MelrosePark => Ok(90408),
485            Self::ElkinsPark => Ok(90409),
486            Self::JenkintownWyncote => Ok(90410),
487            Self::Glenside => Ok(90411),
488            Self::Ardsley => Ok(90412),
489            Self::Roslyn => Ok(90413),
490            Self::Crestmont => Ok(90414),
491            Self::WillowGrove => Ok(90415),
492            Self::Hatboro => Ok(90416),
493            Self::Warminster => Ok(90417),
494            Self::Thorndale => Ok(90501),
495            Self::Downingtown => Ok(90502),
496            Self::Whitford => Ok(90503),
497            Self::Exton => Ok(90504),
498            Self::Malvern => Ok(90505),
499            Self::Paoli => Ok(90506),
500            Self::Daylesford => Ok(90507),
501            Self::Berwyn => Ok(90508),
502            Self::Devon => Ok(90509),
503            Self::Strafford => Ok(90510),
504            Self::Wayne => Ok(90511),
505            Self::StDavids => Ok(90512),
506            Self::Radnor => Ok(90513),
507            Self::Villanova => Ok(90514),
508            Self::Rosemont => Ok(90515),
509            Self::BrynMawr => Ok(90516),
510            Self::Haverford => Ok(90517),
511            Self::Ardmore => Ok(90518),
512            Self::Wynnewood => Ok(90519),
513            Self::Narberth => Ok(90520),
514            Self::Merion => Ok(90521),
515            Self::Overbrook => Ok(90522),
516            Self::NorthHills => Ok(90523),
517            Self::Oreland => Ok(90524),
518            Self::FortWashington => Ok(90525),
519            Self::Ambler => Ok(90526),
520            Self::Penllyn => Ok(90527),
521            Self::GwyneddValley => Ok(90528),
522            Self::NorthWales => Ok(90529),
523            Self::Pennbrook => Ok(90530),
524            Self::Lansdale => Ok(90531),
525            Self::Fortuna => Ok(90532),
526            Self::Colmar => Ok(90533),
527            Self::LinkBelt => Ok(90534),
528            Self::Chalfont => Ok(90535),
529            Self::NewBritain => Ok(90536),
530            Self::DelawareValleyCollege => Ok(90537),
531            Self::Doylestown => Ok(90538),
532            Self::NinthStreetLansdale => Ok(90539),
533            Self::Trenton => Ok(90701),
534            Self::Levittown => Ok(90702),
535            Self::Bristol => Ok(90703),
536            Self::Croydon => Ok(90704),
537            Self::Eddington => Ok(90705),
538            Self::CornwellsHeights => Ok(90706),
539            Self::Torresdale => Ok(90707),
540            Self::HolmesburgJct => Ok(90708),
541            Self::Tacony => Ok(90709),
542            Self::Bridesburg => Ok(90710),
543            Self::NorthPhiladelphiaAmtrak => Ok(90711),
544            Self::Wister => Ok(90712),
545            Self::Germantown => Ok(90713),
546            Self::WashingtonLane => Ok(90714),
547            Self::Stenton => Ok(90715),
548            Self::Sedgwick => Ok(90716),
549            Self::MountAiry => Ok(90717),
550            Self::Wyndmoor => Ok(90718),
551            Self::Gravers => Ok(90719),
552            Self::ChestnutHillEast => Ok(90720),
553            Self::ChestnutHillWest => Ok(90801),
554            Self::Highland => Ok(90802),
555            Self::StMartins => Ok(90803),
556            Self::RichardAllenLane => Ok(90804),
557            Self::Carpenter => Ok(90805),
558            Self::Upsal => Ok(90806),
559            Self::Tulpehocken => Ok(90807),
560            Self::CheltenAvenue => Ok(90808),
561            Self::QueenLane => Ok(90809),
562            Self::NorthPhiladelphia => Ok(90810),
563            Self::Olney => Ok(90811),
564            Self::Lawndale => Ok(90812),
565            Self::Cheltenham => Ok(90813),
566            Self::Ryers => Ok(90814),
567            Self::FoxChase => Ok(90815),
568            Self::Unknown(ref station) => {
569                Err(Error::UnknownRegionalRailStation(station.to_string()))
570            }
571        }
572    }
573
574    pub fn lat_lon(&self) -> Result<(f64, f64), Error> {
575        match *self {
576            Self::Cynwyd => Ok((40.0066667, -75.2316667)),
577            Self::Bala => Ok((40.0011111, -75.2277778)),
578            Self::WynnefieldAvenue => Ok((39.9900000, -75.2255556)),
579            Self::Gray30thStreet => Ok((39.9566667, -75.1816667)),
580            Self::SuburbanStation => Ok((39.9538889, -75.1677778)),
581            Self::JeffersonStation => Ok((39.9525000, -75.1580556)),
582            Self::TempleUniversity => Ok((39.9813889, -75.1494444)),
583            Self::NorthBroad => Ok((39.9922222, -75.1538889)),
584            Self::WayneJunction => Ok((40.0222222, -75.1600000)),
585            Self::Newark => Ok((39.6705556, -75.7527778)),
586            Self::ChurchmansCrossing => Ok((39.6950000, -75.6725000)),
587            Self::Wilmington => Ok((39.7372222, -75.5511111)),
588            Self::Claymont => Ok((39.80429071, -75.44604643)),
589            Self::MarcusHook => Ok((39.8216667, -75.4194444)),
590            Self::HighlandAvenue => Ok((39.8336111, -75.3933333)),
591            Self::Chester => Ok((39.8497222, -75.3600000)),
592            Self::Eddystone => Ok((39.8572222, -75.3422222)),
593            Self::CrumLynne => Ok((39.8719444, -75.3311111)),
594            Self::RidleyPark => Ok((39.8805556, -75.3222222)),
595            Self::ProspectParkMoore => Ok((39.8883333, -75.3088889)),
596            Self::Norwood => Ok((39.8916667, -75.3016667)),
597            Self::Glenolden => Ok((39.8963889, -75.2900000)),
598            Self::Folcroft => Ok((39.9005556, -75.2797222)),
599            Self::SharonHill => Ok((39.9044444, -75.2708333)),
600            Self::CurtisPark => Ok((39.9080556, -75.2650000)),
601            Self::Darby => Ok((39.9130556, -75.2544444)),
602            Self::Allegheny => Ok((40.0036111, -75.1647222)),
603            Self::EastFalls => Ok((40.0113889, -75.1919444)),
604            Self::Wissahickon => Ok((40.0166667, -75.2102778)),
605            Self::Manayunk => Ok((40.0269444, -75.2250000)),
606            Self::IvyRidge => Ok((40.0341667, -75.2355556)),
607            Self::Miquon => Ok((40.0586111, -75.2663889)),
608            Self::SpringMill => Ok((40.0741667, -75.2861111)),
609            Self::Conshohocken => Ok((40.073009, -75.3105619)),
610            Self::NorristownTC => Ok((40.1127778, -75.3441667)),
611            Self::MainStreet => Ok((40.1172222, -75.3486111)),
612            Self::NorristownElmStreet => Ok((40.1208333, -75.3450000)),
613            Self::Wawa => Ok((39.901147, -75.459633)),
614            Self::Elwyn => Ok((39.9075000, -75.4116667)),
615            Self::Media => Ok((39.9144444, -75.3950000)),
616            Self::MoylanRoseValley => Ok((39.9061111, -75.3886111)),
617            Self::Wallingford => Ok((39.9036111, -75.3719444)),
618            Self::Swarthmore => Ok((39.9022222, -75.3508333)),
619            Self::Morton => Ok((39.9077778, -75.3288889)),
620            Self::Secane => Ok((39.9158333, -75.3097222)),
621            Self::Primos => Ok((39.9216667, -75.2983333)),
622            Self::CliftonAldan => Ok((39.9266667, -75.2902778)),
623            Self::Gladstone => Ok((39.9327778, -75.2822222)),
624            Self::Lansdowne => Ok((39.9375000, -75.2708333)),
625            Self::FernwoodYeadon => Ok((39.9397222, -75.2558333)),
626            Self::Angora => Ok((39.9447222, -75.2386111)),
627            Self::FortyNinthStreet => Ok((39.9436111, -75.2166667)),
628            Self::Noble => Ok((40.1044444, -75.1241667)),
629            Self::Rydal => Ok((40.1075000, -75.1105556)),
630            Self::Meadowbrook => Ok((40.1113889, -75.0925000)),
631            Self::Bethayres => Ok((40.1166667, -75.0683333)),
632            Self::Philmont => Ok((40.1219444, -75.0436111)),
633            Self::ForestHills => Ok((40.1277778, -75.0205556)),
634            Self::Somerton => Ok((40.1305556, -75.0119444)),
635            Self::Trevose => Ok((40.1402778, -74.9825000)),
636            Self::Neshaminy => Ok((40.1469444, -74.9616667)),
637            Self::Langhorne => Ok((40.1608333, -74.9125000)),
638            Self::Woodbourne => Ok((40.1925000, -74.8891667)),
639            Self::Yardley => Ok((40.2352778, -74.8305556)),
640            Self::WestTrenton => Ok((40.2577778, -74.8152778)),
641            Self::AirportTerminalEF => Ok((39.8794444, -75.2397222)),
642            Self::AirportTerminalCD => Ok((39.8780556, -75.2400000)),
643            Self::AirportTerminalB => Ok((39.8772222, -75.2413889)),
644            Self::AirportTerminalA => Ok((39.8761111, -75.2452778)),
645            Self::Eastwick => Ok((39.8927778, -75.2438889)),
646            Self::PennMedicineStation => Ok((39.9480556, -75.1902778)),
647            Self::FernRockTC => Ok((40.0405556, -75.1347222)),
648            Self::MelrosePark => Ok((40.0594444, -75.1291667)),
649            Self::ElkinsPark => Ok((40.0713889, -75.1277778)),
650            Self::JenkintownWyncote => Ok((40.0927778, -75.1375000)),
651            Self::Glenside => Ok((40.1013889, -75.1536111)),
652            Self::Ardsley => Ok((40.1141667, -75.1530556)),
653            Self::Roslyn => Ok((40.1208333, -75.1341667)),
654            Self::Crestmont => Ok((40.1333333, -75.1186111)),
655            Self::WillowGrove => Ok((40.1438889, -75.1141667)),
656            Self::Hatboro => Ok((40.1761111, -75.1025000)),
657            Self::Warminster => Ok((40.1952778, -75.0891667)),
658            Self::Thorndale => Ok((39.9927778, -75.7636111)),
659            Self::Downingtown => Ok((40.0022222, -75.7102778)),
660            Self::Whitford => Ok((40.0147222, -75.6380556)),
661            Self::Exton => Ok((40.0191667, -75.6227778)),
662            Self::Malvern => Ok((40.0363889, -75.5155556)),
663            Self::Paoli => Ok((40.0430556, -75.4827778)),
664            Self::Daylesford => Ok((40.0430556, -75.4605556)),
665            Self::Berwyn => Ok((40.0480556, -75.4422222)),
666            Self::Devon => Ok((40.0472222, -75.4227778)),
667            Self::Strafford => Ok((40.0494444, -75.4030556)),
668            Self::Wayne => Ok((40.0458333, -75.3866667)),
669            Self::StDavids => Ok((40.0438889, -75.3725000)),
670            Self::Radnor => Ok((40.0447222, -75.3588889)),
671            Self::Villanova => Ok((40.0383333, -75.3416667)),
672            Self::Rosemont => Ok((40.0277778, -75.3266667)),
673            Self::BrynMawr => Ok((40.0219444, -75.3163889)),
674            Self::Haverford => Ok((40.0138889, -75.2997222)),
675            Self::Ardmore => Ok((40.0083333, -75.2902778)),
676            Self::Wynnewood => Ok((40.0027778, -75.2725000)),
677            Self::Narberth => Ok((40.0047222, -75.2613889)),
678            Self::Merion => Ok((39.9986111, -75.2513889)),
679            Self::Overbrook => Ok((39.9894444, -75.2494444)),
680            Self::NorthHills => Ok((40.1119444, -75.1694444)),
681            Self::Oreland => Ok((40.1183333, -75.1838889)),
682            Self::FortWashington => Ok((40.1358333, -75.2122222)),
683            Self::Ambler => Ok((40.1536111, -75.2247222)),
684            Self::Penllyn => Ok((40.1700000, -75.2441667)),
685            Self::GwyneddValley => Ok((40.1847222, -75.2569444)),
686            Self::NorthWales => Ok((40.2141667, -75.2772222)),
687            Self::Pennbrook => Ok((40.2302778, -75.2816667)),
688            Self::Lansdale => Ok((40.2427778, -75.2850000)),
689            Self::Fortuna => Ok((40.2594444, -75.2661111)),
690            Self::Colmar => Ok((40.2683333, -75.2544444)),
691            Self::LinkBelt => Ok((40.2738889, -75.2466667)),
692            Self::Chalfont => Ok((40.2877778, -75.2097222)),
693            Self::NewBritain => Ok((40.2975000, -75.1797222)),
694            Self::DelawareValleyCollege => Ok((40.2972222, -75.1616667)),
695            Self::Doylestown => Ok((40.3063889, -75.1302778)),
696            Self::NinthStreetLansdale => Ok((40.2500000, -75.2791667)),
697            Self::Trenton => Ok((40.2177778, -74.7550000)),
698            Self::Levittown => Ok((40.1402778, -74.8169444)),
699            Self::Bristol => Ok((40.1047222, -74.8547222)),
700            Self::Croydon => Ok((40.0936111, -74.9066667)),
701            Self::Eddington => Ok((40.0830556, -74.9336111)),
702            Self::CornwellsHeights => Ok((40.0716667, -74.9522222)),
703            Self::Torresdale => Ok((40.0544444, -74.9844444)),
704            Self::HolmesburgJct => Ok((40.0327778, -75.0236111)),
705            Self::Tacony => Ok((40.0233333, -75.0388889)),
706            Self::Bridesburg => Ok((40.0105556, -75.0697222)),
707            Self::NorthPhiladelphiaAmtrak => Ok((39.9972222, -75.1550000)),
708            Self::Wister => Ok((40.0361111, -75.1611111)),
709            Self::Germantown => Ok((40.0375000, -75.1716667)),
710            Self::WashingtonLane => Ok((40.0508333, -75.1713889)),
711            Self::Stenton => Ok((40.0605556, -75.1786111)),
712            Self::Sedgwick => Ok((40.0627778, -75.1852778)),
713            Self::MountAiry => Ok((40.0652778, -75.1908333)),
714            Self::Wyndmoor => Ok((40.0733333, -75.1966667)),
715            Self::Gravers => Ok((40.0775000, -75.2016667)),
716            Self::ChestnutHillEast => Ok((40.0811111, -75.2072222)),
717            Self::ChestnutHillWest => Ok((40.0763889, -75.2083333)),
718            Self::Highland => Ok((40.0705556, -75.2111111)),
719            Self::StMartins => Ok((40.0658333, -75.2044444)),
720            Self::RichardAllenLane => Ok((40.0575000, -75.1947222)),
721            Self::Carpenter => Ok((40.0511111, -75.1913889)),
722            Self::Upsal => Ok((40.0425000, -75.1900000)),
723            Self::Tulpehocken => Ok((40.0352778, -75.1869444)),
724            Self::CheltenAvenue => Ok((40.0300000, -75.1808333)),
725            Self::QueenLane => Ok((40.0233333, -75.1780556)),
726            Self::NorthPhiladelphia => Ok((39.9977778, -75.1563889)),
727            Self::Olney => Ok((40.0333333, -75.1227778)),
728            Self::Lawndale => Ok((40.0513889, -75.1030556)),
729            Self::Cheltenham => Ok((40.0580556, -75.0927778)),
730            Self::Ryers => Ok((40.0641667, -75.0863889)),
731            Self::FoxChase => Ok((40.0763889, -75.0833333)),
732            Self::Unknown(ref station) => {
733                Err(Error::UnknownRegionalRailStation(station.to_string()))
734            }
735        }
736    }
737}
738
739#[derive(
740    Clone,
741    Debug,
742    Deserialize,
743    Display,
744    EnumString,
745    EnumCount,
746    EnumIter,
747    PartialEq,
748    Eq,
749    PartialOrd,
750    Ord,
751    Hash,
752)]
753pub enum NhslStop {
754    #[strum(serialize = "Norristown Transportation Center - NHSL")]
755    NorristownTransportationCenter,
756    #[strum(serialize = "Bridgeport Station - NHSL")]
757    BridgeportStation,
758    #[strum(serialize = "DeKalb St Station - NHSL")]
759    DeKalbStStation,
760    #[strum(serialize = "Hughes Park Station - NHSL")]
761    HughesParkStation,
762    #[strum(serialize = "Gulph Mills Station - NHSL")]
763    GulphMillsStation,
764    #[strum(serialize = "Matsonford Station - NHSL")]
765    MatsonfordStation,
766    #[strum(serialize = "County Line Station - NHSL")]
767    CountyLineStation,
768    #[strum(serialize = "Radnor Station - NHSL")]
769    RadnorStation,
770    #[strum(serialize = "Villanova Station - NHSL")]
771    VillanovaStation,
772    #[strum(serialize = "Stadium Station - NHSL")]
773    StadiumStation,
774    #[strum(serialize = "Garrett Hill Station - NHSL")]
775    GarrettHillStation,
776    #[strum(serialize = "Roberts Rd Station - NHSL")]
777    RobertsRdStation,
778    #[strum(serialize = "Bryn Mawr Station - NHSL")]
779    BrynMawrStation,
780    #[strum(serialize = "Haverford Station - NHSL")]
781    HaverfordStation,
782    #[strum(serialize = "Ardmore Junction Station - NHSL")]
783    ArdmoreJunctionStation,
784    #[strum(serialize = "Wynnewood Rd Station - NHSL")]
785    WynnewoodRdStation,
786    #[strum(serialize = "Beechwood Brookline Station - NHSL")]
787    BeechwoodBrooklineStation,
788    #[strum(serialize = "Penfield Station Manoa Rd - NHSL")]
789    PenfieldStationManoaRd,
790    #[strum(serialize = "Township Line Rd Station - NHSL")]
791    TownshipLineRdStation,
792    #[strum(serialize = "Parkview Station - NHSL")]
793    ParkviewStation,
794    #[strum(serialize = "69th St Transportation Center - NHSL")]
795    SixtyNinthStTransportationCenter,
796}