1use serde::de::{Deserialize, Deserializer};
2use serde::ser::{Serialize, Serializer};
3
4#[derive(Debug, Serialize, Eq, PartialEq, Hash)]
6pub enum ObjectType {
7 Agency,
9 Stop,
11 Route,
13 Trip,
15 Calendar,
17 Shape,
19 Fare,
21 Pathway,
23 Level,
25}
26
27#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
29pub enum LocationType {
30 #[default]
32 StopPoint,
33 StopArea,
35 StationEntrance,
37 GenericNode,
39 BoardingArea,
41 Unknown(i16),
43}
44
45fn serialize_i16_as_str<S: Serializer>(s: S, value: i16) -> Result<S::Ok, S::Error> {
46 s.serialize_str(&value.to_string())
47}
48impl<'de> Deserialize<'de> for LocationType {
49 fn deserialize<D>(deserializer: D) -> Result<LocationType, D::Error>
50 where
51 D: Deserializer<'de>,
52 {
53 let s = <&str>::deserialize(deserializer)?;
54 Ok(match s {
55 "" | "0" => LocationType::StopPoint,
56 "1" => LocationType::StopArea,
57 "2" => LocationType::StationEntrance,
58 "3" => LocationType::GenericNode,
59 "4" => LocationType::BoardingArea,
60 s => LocationType::Unknown(s.parse().map_err(|_| {
61 serde::de::Error::custom(format!(
62 "invalid value for LocationType, must be an integer: {s}"
63 ))
64 })?),
65 })
66 }
67}
68
69impl Serialize for LocationType {
70 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71 where
72 S: Serializer,
73 {
74 serialize_i16_as_str(
76 serializer,
77 match self {
78 LocationType::StopPoint => 0,
79 LocationType::StopArea => 1,
80 LocationType::StationEntrance => 2,
81 LocationType::GenericNode => 3,
82 LocationType::BoardingArea => 4,
83 LocationType::Unknown(i) => *i,
84 },
85 )
86 }
87}
88
89#[derive(Debug, Clone, derive_more::TryFrom, Copy, PartialEq, Eq, Hash)]
90#[repr(i16)]
91#[try_from(repr)]
92pub enum ExtendedRouteType {
94 Railway = 100,
96 HighSpeedRail = 101,
98 LongDistanceTrains = 102,
100 InterRegionalRail = 103,
102 CarTransportRail = 104,
104 SleeperRail = 105,
106 RegionalRail = 106,
108 TouristRailway = 107,
110 RailShuttleWithinComplex = 108,
112 SuburbanRailway = 109,
114 ReplacementRail = 110,
116 SpecialRail = 111,
118 LorryTransportRail = 112,
120 OtherRail = 113,
122 CrossCountryRail = 114,
124 VehicleTransportRail = 115,
126 RackAndPinionRailway = 116,
128 AdditionalRail = 117,
130
131 Coach = 200,
133 InternationalCoach = 201,
135 NationalCoach = 202,
137 ShuttleCoach = 203,
139 RegionalCoach = 204,
141 SpecialCoach = 205,
143 SightseeingCoach = 206,
145 TouristCoach = 207,
147 CommuterCoach = 208,
149 OtherCoach = 209,
151
152 UrbanRailway = 400,
154 Metro = 401,
156 Underground = 402,
158 UrbanRailwayServiceDetail = 403,
160 OtherUrbanRailway = 404,
162 Monorail = 405,
164
165 Bus = 700,
167 RegionalBus = 701,
169 ExpressBus = 702,
171 StoppingBus = 703,
173 LocalBus = 704,
175 NightBus = 705,
177 PostBus = 706,
179 SpecialNeedsBus = 707,
181 MobilityBus = 708,
183 MobilityBusForRegisteredDisabled = 709,
185 SightseeingBus = 710,
187 ShuttleBus = 711,
189 SchoolBus = 712,
191 SchoolAndPublicServiceBus = 713,
193 RailReplacementBus = 714,
195 DemandAndResponseBus = 715,
197 OtherBus = 716,
199
200 Trolleybus = 800,
202
203 Tram = 900,
205 CityTram = 901,
207 LocalTram = 902,
209 RegionalTram = 903,
211 SightseeingTram = 904,
213 ShuttleTram = 905,
215 OtherTram = 906,
217
218 WaterTransport = 1000,
220 Air = 1100,
222 Ferry = 1200,
224
225 AerialLift = 1300,
227 Telecabin = 1301,
229 CableCar = 1302,
231 Elevator = 1303,
233 ChairLift = 1304,
235 DragLift = 1305,
237 SmallTelecabin = 1306,
239 OtherTelecabin = 1307,
241
242 Funicular = 1400,
245
246 Taxi = 1500,
248 CommunalTaxi = 1501,
250 WaterTaxi = 1502,
252 RailTaxi = 1503,
254 BikeTaxi = 1504,
256 LicensedTaxi = 1505,
258 PrivateHireServiceVehicle = 1506,
260 OtherTaxi = 1507,
262
263 MiscellaneousService = 1700,
265 HorseDrawnCarriage = 1702,
267}
268
269#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
273pub enum RouteType {
274 Tramway,
276 Subway,
278 Rail,
280 #[default]
282 Bus,
283 Ferry,
285 CableCar,
287 Gondola,
289 Funicular,
291 Extended(ExtendedRouteType),
293 Other(i16),
295}
296
297impl ExtendedRouteType {
298 pub fn to_standard_route_type(&self) -> RouteType {
301 let int = *self as i16;
302 let hundreds = int / 100;
303 match hundreds {
304 1 => RouteType::Rail,
305 4 => RouteType::Subway,
306 2 | 7 | 8 => RouteType::Bus,
307 9 => RouteType::Tramway,
308 10 | 12 => RouteType::Ferry,
309 13 => RouteType::Gondola,
310 14 => RouteType::Funicular,
311 _ => RouteType::Extended(*self),
312 }
313 }
314}
315
316impl<'de> Deserialize<'de> for RouteType {
317 fn deserialize<D>(deserializer: D) -> Result<RouteType, D::Error>
318 where
319 D: Deserializer<'de>,
320 {
321 let i = i16::deserialize(deserializer)?;
322 if let Ok(ert) = ExtendedRouteType::try_from(i) {
323 return Ok(RouteType::Extended(ert));
324 }
325
326 Ok(match i {
327 0 => RouteType::Tramway,
328 1 => RouteType::Subway,
329 2 => RouteType::Rail,
330 3 => RouteType::Bus,
331 4 => RouteType::Ferry,
332 5 => RouteType::CableCar,
333 6 => RouteType::Gondola,
334 7 => RouteType::Funicular,
335 _ => RouteType::Other(i),
336 })
337 }
338}
339
340impl Serialize for RouteType {
341 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
342 where
343 S: Serializer,
344 {
345 serializer.serialize_i16(match self {
346 RouteType::Tramway => 0,
347 RouteType::Subway => 1,
348 RouteType::Rail => 2,
349 RouteType::Bus => 3,
350 RouteType::Ferry => 4,
351 RouteType::CableCar => 5,
352 RouteType::Gondola => 6,
353 RouteType::Funicular => 7,
354 RouteType::Extended(ert) => *ert as i16,
355 RouteType::Other(i) => *i,
356 })
357 }
358}
359
360#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
362pub enum PickupDropOffType {
363 #[default]
365 Regular,
366 NotAvailable,
368 ArrangeByPhone,
370 CoordinateWithDriver,
372 Unknown(i16),
374}
375
376impl<'de> Deserialize<'de> for PickupDropOffType {
377 fn deserialize<D>(deserializer: D) -> Result<PickupDropOffType, D::Error>
378 where
379 D: Deserializer<'de>,
380 {
381 let s = <&str>::deserialize(deserializer)?;
382 Ok(match s {
383 "" | "0" => PickupDropOffType::Regular,
384 "1" => PickupDropOffType::NotAvailable,
385 "2" => PickupDropOffType::ArrangeByPhone,
386 "3" => PickupDropOffType::CoordinateWithDriver,
387 s => PickupDropOffType::Unknown(s.parse().map_err(|_| {
388 serde::de::Error::custom(format!(
389 "invalid value for PickupDropOffType, must be an integer: {s}"
390 ))
391 })?),
392 })
393 }
394}
395
396impl Serialize for PickupDropOffType {
397 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
398 where
399 S: Serializer,
400 {
401 serialize_i16_as_str(
403 serializer,
404 match self {
405 PickupDropOffType::Regular => 0,
406 PickupDropOffType::NotAvailable => 1,
407 PickupDropOffType::ArrangeByPhone => 2,
408 PickupDropOffType::CoordinateWithDriver => 3,
409 PickupDropOffType::Unknown(i) => *i,
410 },
411 )
412 }
413}
414
415#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
419pub enum ContinuousPickupDropOff {
420 Continuous,
422 #[default]
424 NotAvailable,
425 ArrangeByPhone,
427 CoordinateWithDriver,
429 Unknown(i16),
431}
432
433impl Serialize for ContinuousPickupDropOff {
434 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
435 where
436 S: Serializer,
437 {
438 serialize_i16_as_str(
440 serializer,
441 match self {
442 ContinuousPickupDropOff::Continuous => 0,
443 ContinuousPickupDropOff::NotAvailable => 1,
444 ContinuousPickupDropOff::ArrangeByPhone => 2,
445 ContinuousPickupDropOff::CoordinateWithDriver => 3,
446 ContinuousPickupDropOff::Unknown(i) => *i,
447 },
448 )
449 }
450}
451
452impl<'de> Deserialize<'de> for ContinuousPickupDropOff {
453 fn deserialize<D>(deserializer: D) -> Result<ContinuousPickupDropOff, D::Error>
454 where
455 D: Deserializer<'de>,
456 {
457 let s = <&str>::deserialize(deserializer)?;
458 Ok(match s {
459 "0" => ContinuousPickupDropOff::Continuous,
460 "" | "1" => ContinuousPickupDropOff::NotAvailable,
461 "2" => ContinuousPickupDropOff::ArrangeByPhone,
462 "3" => ContinuousPickupDropOff::CoordinateWithDriver,
463 s => ContinuousPickupDropOff::Unknown(s.parse().map_err(|_| {
464 serde::de::Error::custom(format!(
465 "invalid value for ContinuousPickupDropOff, must be an integer: {s}"
466 ))
467 })?),
468 })
469 }
470}
471
472#[derive(Debug, Default, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
474pub enum TimepointType {
475 #[serde(rename = "0")]
477 Approximate = 0,
478 #[default]
480 #[serde(rename = "1")]
481 Exact = 1,
482}
483
484impl<'de> Deserialize<'de> for TimepointType {
485 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
486 where
487 D: Deserializer<'de>,
488 {
489 let s = <&str>::deserialize(deserializer)?;
490 match s {
491 "" | "1" => Ok(Self::Exact),
492 "0" => Ok(Self::Approximate),
493 v => Err(serde::de::Error::custom(format!(
494 "invalid value for timepoint: {v}"
495 ))),
496 }
497 }
498}
499
500#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
502pub enum Availability {
503 #[default]
505 InformationNotAvailable,
506 Available,
508 NotAvailable,
510 Unknown(i16),
512}
513
514impl<'de> Deserialize<'de> for Availability {
515 fn deserialize<D>(deserializer: D) -> Result<Availability, D::Error>
516 where
517 D: Deserializer<'de>,
518 {
519 let s = <&str>::deserialize(deserializer)?;
520 Ok(match s {
521 "" | "0" => Availability::InformationNotAvailable,
522 "1" => Availability::Available,
523 "2" => Availability::NotAvailable,
524 s => Availability::Unknown(s.parse().map_err(|_| {
525 serde::de::Error::custom(format!(
526 "invalid value for Availability, must be an integer: {s}"
527 ))
528 })?),
529 })
530 }
531}
532
533impl Serialize for Availability {
534 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
535 where
536 S: Serializer,
537 {
538 serialize_i16_as_str(
540 serializer,
541 match self {
542 Availability::InformationNotAvailable => 0,
543 Availability::Available => 1,
544 Availability::NotAvailable => 2,
545 Availability::Unknown(i) => *i,
546 },
547 )
548 }
549}
550
551#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)]
553pub enum Exception {
554 #[serde(rename = "1")]
556 Added,
557 #[serde(rename = "2")]
559 Deleted,
560}
561
562#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
564pub enum DirectionType {
565 #[serde(rename = "0")]
567 Outbound,
568 #[serde(rename = "1")]
570 Inbound,
571}
572
573#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
575pub enum BikesAllowedType {
576 #[default]
578 NoBikeInfo,
579 AtLeastOneBike,
581 NoBikesAllowed,
583 Unknown(i16),
585}
586
587impl<'de> Deserialize<'de> for BikesAllowedType {
588 fn deserialize<D>(deserializer: D) -> Result<BikesAllowedType, D::Error>
589 where
590 D: Deserializer<'de>,
591 {
592 let s = <&str>::deserialize(deserializer)?;
593 Ok(match s {
594 "" | "0" => BikesAllowedType::NoBikeInfo,
595 "1" => BikesAllowedType::AtLeastOneBike,
596 "2" => BikesAllowedType::NoBikesAllowed,
597 s => BikesAllowedType::Unknown(s.parse().map_err(|_| {
598 serde::de::Error::custom(format!(
599 "invalid value for BikeAllowedType, must be an integer: {s}"
600 ))
601 })?),
602 })
603 }
604}
605
606impl Serialize for BikesAllowedType {
607 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
608 where
609 S: Serializer,
610 {
611 serialize_i16_as_str(
613 serializer,
614 match self {
615 BikesAllowedType::NoBikeInfo => 0,
616 BikesAllowedType::AtLeastOneBike => 1,
617 BikesAllowedType::NoBikesAllowed => 2,
618 BikesAllowedType::Unknown(i) => *i,
619 },
620 )
621 }
622}
623
624#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
626pub enum CarsAllowedType {
627 #[default]
629 NoCarInfo,
630 AtLeastOneCar,
632 NoCarsAllowed,
634 Unknown(i16),
636}
637
638impl<'de> Deserialize<'de> for CarsAllowedType {
639 fn deserialize<D>(deserializer: D) -> Result<CarsAllowedType, D::Error>
640 where
641 D: Deserializer<'de>,
642 {
643 let s = <&str>::deserialize(deserializer)?;
644 Ok(match s {
645 "" | "0" => CarsAllowedType::NoCarInfo,
646 "1" => CarsAllowedType::AtLeastOneCar,
647 "2" => CarsAllowedType::NoCarsAllowed,
648 s => CarsAllowedType::Unknown(s.parse().map_err(|_| {
649 serde::de::Error::custom(format!(
650 "invalid value for CarsAllowedType, must be an integer: {s}"
651 ))
652 })?),
653 })
654 }
655}
656
657impl Serialize for CarsAllowedType {
658 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
659 where
660 S: Serializer,
661 {
662 serialize_i16_as_str(
664 serializer,
665 match self {
666 CarsAllowedType::NoCarInfo => 0,
667 CarsAllowedType::AtLeastOneCar => 1,
668 CarsAllowedType::NoCarsAllowed => 2,
669 CarsAllowedType::Unknown(i) => *i,
670 },
671 )
672 }
673}
674#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
676pub enum PaymentMethod {
677 #[serde(rename = "0")]
679 Aboard,
680 #[serde(rename = "1")]
682 PreBoarding,
683}
684
685#[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
687pub enum ExactTimes {
688 FrequencyBased = 0,
690 ScheduleBased = 1,
692}
693
694impl<'de> Deserialize<'de> for ExactTimes {
695 fn deserialize<D>(deserializer: D) -> Result<ExactTimes, D::Error>
696 where
697 D: Deserializer<'de>,
698 {
699 let s = <&str>::deserialize(deserializer)?;
700 Ok(match s {
701 "" | "0" => ExactTimes::FrequencyBased,
702 "1" => ExactTimes::ScheduleBased,
703 &_ => {
704 return Err(serde::de::Error::custom(format!(
705 "Invalid value `{s}`, expected 0 or 1"
706 )));
707 }
708 })
709 }
710}
711
712#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
714pub enum Transfers {
715 #[default]
717 Unlimited,
718 NoTransfer,
720 UniqueTransfer,
722 TwoTransfers,
724 Other(i16),
726}
727
728impl<'de> Deserialize<'de> for Transfers {
729 fn deserialize<D>(deserializer: D) -> Result<Transfers, D::Error>
730 where
731 D: Deserializer<'de>,
732 {
733 let i = Option::<i16>::deserialize(deserializer)?;
734 Ok(match i {
735 Some(0) => Transfers::NoTransfer,
736 Some(1) => Transfers::UniqueTransfer,
737 Some(2) => Transfers::TwoTransfers,
738 Some(a) => Transfers::Other(a),
739 None => Transfers::default(),
740 })
741 }
742}
743
744impl Serialize for Transfers {
745 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
746 where
747 S: Serializer,
748 {
749 match self {
750 Transfers::NoTransfer => serialize_i16_as_str(serializer, 0),
751 Transfers::UniqueTransfer => serialize_i16_as_str(serializer, 1),
752 Transfers::TwoTransfers => serialize_i16_as_str(serializer, 2),
753 Transfers::Other(a) => serialize_i16_as_str(serializer, *a),
754 Transfers::Unlimited => serializer.serialize_none(),
755 }
756 }
757}
758#[derive(Debug, Serialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
760pub enum TransferType {
761 #[serde(rename = "0")]
763 #[default]
764 Recommended,
765 #[serde(rename = "1")]
767 Timed,
768 #[serde(rename = "2")]
770 MinTime,
771 #[serde(rename = "3")]
773 Impossible,
774 #[serde(rename = "4")]
776 StayOnBoard,
777 #[serde(rename = "5")]
780 MustAlight,
781}
782
783impl<'de> Deserialize<'de> for TransferType {
784 fn deserialize<D>(deserializer: D) -> Result<TransferType, D::Error>
785 where
786 D: Deserializer<'de>,
787 {
788 let s = <&str>::deserialize(deserializer)?;
789 Ok(match s {
790 "" | "0" => TransferType::Recommended,
791 "1" => TransferType::Timed,
792 "2" => TransferType::MinTime,
793 "3" => TransferType::Impossible,
794 "4" => TransferType::StayOnBoard,
795 "5" => TransferType::MustAlight,
796 s => {
797 return Err(serde::de::Error::custom(format!(
798 "Invalid value `{s}`, expected 0, 1, 2, 3, 4, 5"
799 )));
800 }
801 })
802 }
803}
804
805#[derive(Debug, Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
807pub enum PathwayMode {
808 #[serde(rename = "1")]
810 #[default]
811 Walkway,
812 #[serde(rename = "2")]
814 Stairs,
815 #[serde(rename = "3")]
817 MovingSidewalk,
818 #[serde(rename = "4")]
820 Escalator,
821 #[serde(rename = "5")]
823 Elevator,
824 #[serde(rename = "6")]
827 FareGate,
828 #[serde(rename = "7")]
831 ExitGate,
832}
833
834#[derive(Debug, Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
836pub enum PathwayDirectionType {
837 #[serde(rename = "0")]
839 #[default]
840 Unidirectional,
841 #[serde(rename = "1")]
843 Bidirectional,
844}
845
846#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
848pub enum FareMediaType {
849 #[serde(rename = "0")]
851 None,
852 #[serde(rename = "1")]
854 PhysicalPaperTicket,
855 #[serde(rename = "2")]
857 PhysicalTransitCard,
858 #[serde(rename = "3")]
860 CEmv,
861 #[serde(rename = "4")]
863 MobileApp,
864}
865
866#[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
868pub enum DefaultFareCategory {
869 NotDefault = 0,
871 Default = 1,
873}
874
875impl<'de> Deserialize<'de> for DefaultFareCategory {
876 fn deserialize<D>(deserializer: D) -> Result<DefaultFareCategory, D::Error>
877 where
878 D: Deserializer<'de>,
879 {
880 let s = <&str>::deserialize(deserializer)?;
881 Ok(match s {
882 "" | "0" => DefaultFareCategory::NotDefault,
883 "1" => DefaultFareCategory::Default,
884 &_ => {
885 return Err(serde::de::Error::custom(format!(
886 "Invalid value `{s}`, expected 0 or 1"
887 )));
888 }
889 })
890 }
891}
892
893#[derive(Debug, Default, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
895pub enum TicketingType {
896 #[default]
898 #[serde(rename = "0")]
899 Available,
900 #[serde(rename = "1")]
902 Unavailable,
903}