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}
24
25#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
27pub enum LocationType {
28 #[default]
30 StopPoint,
31 StopArea,
33 StationEntrance,
35 GenericNode,
37 BoardingArea,
39 Unknown(i16),
41}
42
43fn serialize_i16_as_str<S: Serializer>(s: S, value: i16) -> Result<S::Ok, S::Error> {
44 s.serialize_str(&value.to_string())
45}
46impl<'de> Deserialize<'de> for LocationType {
47 fn deserialize<D>(deserializer: D) -> Result<LocationType, D::Error>
48 where
49 D: Deserializer<'de>,
50 {
51 let s = <&str>::deserialize(deserializer)?;
52 Ok(match s {
53 "" | "0" => LocationType::StopPoint,
54 "1" => LocationType::StopArea,
55 "2" => LocationType::StationEntrance,
56 "3" => LocationType::GenericNode,
57 "4" => LocationType::BoardingArea,
58 s => LocationType::Unknown(s.parse().map_err(|_| {
59 serde::de::Error::custom(format!(
60 "invalid value for LocationType, must be an integer: {s}"
61 ))
62 })?),
63 })
64 }
65}
66
67impl Serialize for LocationType {
68 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69 where
70 S: Serializer,
71 {
72 serialize_i16_as_str(
74 serializer,
75 match self {
76 LocationType::StopPoint => 0,
77 LocationType::StopArea => 1,
78 LocationType::StationEntrance => 2,
79 LocationType::GenericNode => 3,
80 LocationType::BoardingArea => 4,
81 LocationType::Unknown(i) => *i,
82 },
83 )
84 }
85}
86
87#[derive(Debug, Clone, derive_more::TryFrom, Copy, PartialEq, Eq, Hash)]
88#[repr(i16)]
89#[try_from(repr)]
90pub enum ExtendedRouteType {
92 Railway = 100,
94 HighSpeedRail = 101,
96 LongDistanceTrains = 102,
98 InterRegionalRail = 103,
100 CarTransportRail = 104,
102 SleeperRail = 105,
104 RegionalRail = 106,
106 TouristRailway = 107,
108 RailShuttleWithinComplex = 108,
110 SuburbanRailway = 109,
112 ReplacementRail = 110,
114 SpecialRail = 111,
116 LorryTransportRail = 112,
118 OtherRail = 113,
120 CrossCountryRail = 114,
122 VehicleTransportRail = 115,
124 RackAndPinionRailway = 116,
126 AdditionalRail = 117,
128
129 Coach = 200,
131 InternationalCoach = 201,
133 NationalCoach = 202,
135 ShuttleCoach = 203,
137 RegionalCoach = 204,
139 SpecialCoach = 205,
141 SightseeingCoach = 206,
143 TouristCoach = 207,
145 CommuterCoach = 208,
147 OtherCoach = 209,
149
150 UrbanRailway = 400,
152 Metro = 401,
154 Underground = 402,
156 UrbanRailwayServiceDetail = 403,
158 OtherUrbanRailway = 404,
160 Monorail = 405,
162
163 Bus = 700,
165 RegionalBus = 701,
167 ExpressBus = 702,
169 StoppingBus = 703,
171 LocalBus = 704,
173 NightBus = 705,
175 PostBus = 706,
177 SpecialNeedsBus = 707,
179 MobilityBus = 708,
181 MobilityBusForRegisteredDisabled = 709,
183 SightseeingBus = 710,
185 ShuttleBus = 711,
187 SchoolBus = 712,
189 SchoolAndPublicServiceBus = 713,
191 RailReplacementBus = 714,
193 DemandAndResponseBus = 715,
195 OtherBus = 716,
197
198 Trolleybus = 800,
200
201 Tram = 900,
203 CityTram = 901,
205 LocalTram = 902,
207 RegionalTram = 903,
209 SightseeingTram = 904,
211 ShuttleTram = 905,
213 OtherTram = 906,
215
216 WaterTransport = 1000,
218 Air = 1100,
220 Ferry = 1200,
222
223 AerialLift = 1300,
225 Telecabin = 1301,
227 CableCar = 1302,
229 Elevator = 1303,
231 ChairLift = 1304,
233 DragLift = 1305,
235 SmallTelecabin = 1306,
237 OtherTelecabin = 1307,
239
240 Funicular = 1400,
243
244 Taxi = 1500,
246 CommunalTaxi = 1501,
248 WaterTaxi = 1502,
250 RailTaxi = 1503,
252 BikeTaxi = 1504,
254 LicensedTaxi = 1505,
256 PrivateHireServiceVehicle = 1506,
258 OtherTaxi = 1507,
260
261 MiscellaneousService = 1700,
263 HorseDrawnCarriage = 1702,
265}
266
267#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
271pub enum RouteType {
272 Tramway,
274 Subway,
276 Rail,
278 #[default]
280 Bus,
281 Ferry,
283 CableCar,
285 Gondola,
287 Funicular,
289 Extended(ExtendedRouteType),
291 Other(i16),
293}
294
295impl ExtendedRouteType {
296 pub fn to_standard_route_type(&self) -> RouteType {
299 let int = *self as i16;
300 let hundreds = int / 100;
301 match hundreds {
302 1 => RouteType::Rail,
303 4 => RouteType::Subway,
304 2 | 7 | 8 => RouteType::Bus,
305 9 => RouteType::Tramway,
306 10 | 12 => RouteType::Ferry,
307 13 => RouteType::Gondola,
308 14 => RouteType::Funicular,
309 _ => RouteType::Extended(*self),
310 }
311 }
312}
313
314impl<'de> Deserialize<'de> for RouteType {
315 fn deserialize<D>(deserializer: D) -> Result<RouteType, D::Error>
316 where
317 D: Deserializer<'de>,
318 {
319 let i = i16::deserialize(deserializer)?;
320 if let Ok(ert) = ExtendedRouteType::try_from(i) {
321 return Ok(RouteType::Extended(ert));
322 }
323
324 Ok(match i {
325 0 => RouteType::Tramway,
326 1 => RouteType::Subway,
327 2 => RouteType::Rail,
328 3 => RouteType::Bus,
329 4 => RouteType::Ferry,
330 5 => RouteType::CableCar,
331 6 => RouteType::Gondola,
332 7 => RouteType::Funicular,
333 _ => RouteType::Other(i),
334 })
335 }
336}
337
338impl Serialize for RouteType {
339 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
340 where
341 S: Serializer,
342 {
343 serializer.serialize_i16(match self {
344 RouteType::Tramway => 0,
345 RouteType::Subway => 1,
346 RouteType::Rail => 2,
347 RouteType::Bus => 3,
348 RouteType::Ferry => 4,
349 RouteType::CableCar => 5,
350 RouteType::Gondola => 6,
351 RouteType::Funicular => 7,
352 RouteType::Extended(ert) => *ert as i16,
353 RouteType::Other(i) => *i,
354 })
355 }
356}
357
358#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
360pub enum PickupDropOffType {
361 #[default]
363 Regular,
364 NotAvailable,
366 ArrangeByPhone,
368 CoordinateWithDriver,
370 Unknown(i16),
372}
373
374impl<'de> Deserialize<'de> for PickupDropOffType {
375 fn deserialize<D>(deserializer: D) -> Result<PickupDropOffType, D::Error>
376 where
377 D: Deserializer<'de>,
378 {
379 let s = <&str>::deserialize(deserializer)?;
380 Ok(match s {
381 "" | "0" => PickupDropOffType::Regular,
382 "1" => PickupDropOffType::NotAvailable,
383 "2" => PickupDropOffType::ArrangeByPhone,
384 "3" => PickupDropOffType::CoordinateWithDriver,
385 s => PickupDropOffType::Unknown(s.parse().map_err(|_| {
386 serde::de::Error::custom(format!(
387 "invalid value for PickupDropOffType, must be an integer: {s}"
388 ))
389 })?),
390 })
391 }
392}
393
394impl Serialize for PickupDropOffType {
395 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
396 where
397 S: Serializer,
398 {
399 serialize_i16_as_str(
401 serializer,
402 match self {
403 PickupDropOffType::Regular => 0,
404 PickupDropOffType::NotAvailable => 1,
405 PickupDropOffType::ArrangeByPhone => 2,
406 PickupDropOffType::CoordinateWithDriver => 3,
407 PickupDropOffType::Unknown(i) => *i,
408 },
409 )
410 }
411}
412
413#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
417pub enum ContinuousPickupDropOff {
418 Continuous,
420 #[default]
422 NotAvailable,
423 ArrangeByPhone,
425 CoordinateWithDriver,
427 Unknown(i16),
429}
430
431impl Serialize for ContinuousPickupDropOff {
432 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
433 where
434 S: Serializer,
435 {
436 serialize_i16_as_str(
438 serializer,
439 match self {
440 ContinuousPickupDropOff::Continuous => 0,
441 ContinuousPickupDropOff::NotAvailable => 1,
442 ContinuousPickupDropOff::ArrangeByPhone => 2,
443 ContinuousPickupDropOff::CoordinateWithDriver => 3,
444 ContinuousPickupDropOff::Unknown(i) => *i,
445 },
446 )
447 }
448}
449
450impl<'de> Deserialize<'de> for ContinuousPickupDropOff {
451 fn deserialize<D>(deserializer: D) -> Result<ContinuousPickupDropOff, D::Error>
452 where
453 D: Deserializer<'de>,
454 {
455 let s = <&str>::deserialize(deserializer)?;
456 Ok(match s {
457 "0" => ContinuousPickupDropOff::Continuous,
458 "" | "1" => ContinuousPickupDropOff::NotAvailable,
459 "2" => ContinuousPickupDropOff::ArrangeByPhone,
460 "3" => ContinuousPickupDropOff::CoordinateWithDriver,
461 s => ContinuousPickupDropOff::Unknown(s.parse().map_err(|_| {
462 serde::de::Error::custom(format!(
463 "invalid value for ContinuousPickupDropOff, must be an integer: {s}"
464 ))
465 })?),
466 })
467 }
468}
469
470#[derive(Debug, Default, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
472pub enum TimepointType {
473 #[serde(rename = "0")]
475 Approximate = 0,
476 #[default]
478 #[serde(rename = "1")]
479 Exact = 1,
480}
481
482impl<'de> Deserialize<'de> for TimepointType {
483 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
484 where
485 D: Deserializer<'de>,
486 {
487 let s = <&str>::deserialize(deserializer)?;
488 match s {
489 "" | "1" => Ok(Self::Exact),
490 "0" => Ok(Self::Approximate),
491 v => Err(serde::de::Error::custom(format!(
492 "invalid value for timepoint: {v}"
493 ))),
494 }
495 }
496}
497
498#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
500pub enum Availability {
501 #[default]
503 InformationNotAvailable,
504 Available,
506 NotAvailable,
508 Unknown(i16),
510}
511
512impl<'de> Deserialize<'de> for Availability {
513 fn deserialize<D>(deserializer: D) -> Result<Availability, D::Error>
514 where
515 D: Deserializer<'de>,
516 {
517 let s = <&str>::deserialize(deserializer)?;
518 Ok(match s {
519 "" | "0" => Availability::InformationNotAvailable,
520 "1" => Availability::Available,
521 "2" => Availability::NotAvailable,
522 s => Availability::Unknown(s.parse().map_err(|_| {
523 serde::de::Error::custom(format!(
524 "invalid value for Availability, must be an integer: {s}"
525 ))
526 })?),
527 })
528 }
529}
530
531impl Serialize for Availability {
532 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
533 where
534 S: Serializer,
535 {
536 serialize_i16_as_str(
538 serializer,
539 match self {
540 Availability::InformationNotAvailable => 0,
541 Availability::Available => 1,
542 Availability::NotAvailable => 2,
543 Availability::Unknown(i) => *i,
544 },
545 )
546 }
547}
548
549#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)]
551pub enum Exception {
552 #[serde(rename = "1")]
554 Added,
555 #[serde(rename = "2")]
557 Deleted,
558}
559
560#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
562pub enum DirectionType {
563 #[serde(rename = "0")]
565 Outbound,
566 #[serde(rename = "1")]
568 Inbound,
569}
570
571#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
573pub enum BikesAllowedType {
574 #[default]
576 NoBikeInfo,
577 AtLeastOneBike,
579 NoBikesAllowed,
581 Unknown(i16),
583}
584
585impl<'de> Deserialize<'de> for BikesAllowedType {
586 fn deserialize<D>(deserializer: D) -> Result<BikesAllowedType, D::Error>
587 where
588 D: Deserializer<'de>,
589 {
590 let s = <&str>::deserialize(deserializer)?;
591 Ok(match s {
592 "" | "0" => BikesAllowedType::NoBikeInfo,
593 "1" => BikesAllowedType::AtLeastOneBike,
594 "2" => BikesAllowedType::NoBikesAllowed,
595 s => BikesAllowedType::Unknown(s.parse().map_err(|_| {
596 serde::de::Error::custom(format!(
597 "invalid value for BikeAllowedType, must be an integer: {s}"
598 ))
599 })?),
600 })
601 }
602}
603
604impl Serialize for BikesAllowedType {
605 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
606 where
607 S: Serializer,
608 {
609 serialize_i16_as_str(
611 serializer,
612 match self {
613 BikesAllowedType::NoBikeInfo => 0,
614 BikesAllowedType::AtLeastOneBike => 1,
615 BikesAllowedType::NoBikesAllowed => 2,
616 BikesAllowedType::Unknown(i) => *i,
617 },
618 )
619 }
620}
621
622#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
624pub enum PaymentMethod {
625 #[serde(rename = "0")]
627 Aboard,
628 #[serde(rename = "1")]
630 PreBoarding,
631}
632
633#[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
635pub enum ExactTimes {
636 FrequencyBased = 0,
638 ScheduleBased = 1,
640}
641
642impl<'de> Deserialize<'de> for ExactTimes {
643 fn deserialize<D>(deserializer: D) -> Result<ExactTimes, D::Error>
644 where
645 D: Deserializer<'de>,
646 {
647 let s = <&str>::deserialize(deserializer)?;
648 Ok(match s {
649 "" | "0" => ExactTimes::FrequencyBased,
650 "1" => ExactTimes::ScheduleBased,
651 &_ => {
652 return Err(serde::de::Error::custom(format!(
653 "Invalid value `{s}`, expected 0 or 1"
654 )));
655 }
656 })
657 }
658}
659
660#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
662pub enum Transfers {
663 #[default]
665 Unlimited,
666 NoTransfer,
668 UniqueTransfer,
670 TwoTransfers,
672 Other(i16),
674}
675
676impl<'de> Deserialize<'de> for Transfers {
677 fn deserialize<D>(deserializer: D) -> Result<Transfers, D::Error>
678 where
679 D: Deserializer<'de>,
680 {
681 let i = Option::<i16>::deserialize(deserializer)?;
682 Ok(match i {
683 Some(0) => Transfers::NoTransfer,
684 Some(1) => Transfers::UniqueTransfer,
685 Some(2) => Transfers::TwoTransfers,
686 Some(a) => Transfers::Other(a),
687 None => Transfers::default(),
688 })
689 }
690}
691
692impl Serialize for Transfers {
693 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
694 where
695 S: Serializer,
696 {
697 match self {
698 Transfers::NoTransfer => serialize_i16_as_str(serializer, 0),
699 Transfers::UniqueTransfer => serialize_i16_as_str(serializer, 1),
700 Transfers::TwoTransfers => serialize_i16_as_str(serializer, 2),
701 Transfers::Other(a) => serialize_i16_as_str(serializer, *a),
702 Transfers::Unlimited => serializer.serialize_none(),
703 }
704 }
705}
706#[derive(Debug, Serialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
708pub enum TransferType {
709 #[serde(rename = "0")]
711 #[default]
712 Recommended,
713 #[serde(rename = "1")]
715 Timed,
716 #[serde(rename = "2")]
718 MinTime,
719 #[serde(rename = "3")]
721 Impossible,
722 #[serde(rename = "4")]
724 StayOnBoard,
725 #[serde(rename = "5")]
728 MustAlight,
729}
730
731impl<'de> Deserialize<'de> for TransferType {
732 fn deserialize<D>(deserializer: D) -> Result<TransferType, D::Error>
733 where
734 D: Deserializer<'de>,
735 {
736 let s = <&str>::deserialize(deserializer)?;
737 Ok(match s {
738 "" | "0" => TransferType::Recommended,
739 "1" => TransferType::Timed,
740 "2" => TransferType::MinTime,
741 "3" => TransferType::Impossible,
742 "4" => TransferType::StayOnBoard,
743 "5" => TransferType::MustAlight,
744 s => {
745 return Err(serde::de::Error::custom(format!(
746 "Invalid value `{s}`, expected 0, 1, 2, 3, 4, 5"
747 )));
748 }
749 })
750 }
751}
752
753#[derive(Debug, Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
755pub enum PathwayMode {
756 #[serde(rename = "1")]
758 #[default]
759 Walkway,
760 #[serde(rename = "2")]
762 Stairs,
763 #[serde(rename = "3")]
765 MovingSidewalk,
766 #[serde(rename = "4")]
768 Escalator,
769 #[serde(rename = "5")]
771 Elevator,
772 #[serde(rename = "6")]
775 FareGate,
776 #[serde(rename = "7")]
779 ExitGate,
780}
781
782#[derive(Debug, Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
784pub enum PathwayDirectionType {
785 #[serde(rename = "0")]
787 #[default]
788 Unidirectional,
789 #[serde(rename = "1")]
791 Bidirectional,
792}
793
794#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
796pub enum FareMediaType {
797 #[serde(rename = "0")]
799 None,
800 #[serde(rename = "1")]
802 PhysicalPaperTicket,
803 #[serde(rename = "2")]
805 PhysicalTransitCard,
806 #[serde(rename = "3")]
808 CEmv,
809 #[serde(rename = "4")]
811 MobileApp,
812}
813
814#[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
816pub enum DefaultFareCategory {
817 NotDefault = 0,
819 Default = 1,
821}
822
823impl<'de> Deserialize<'de> for DefaultFareCategory {
824 fn deserialize<D>(deserializer: D) -> Result<DefaultFareCategory, D::Error>
825 where
826 D: Deserializer<'de>,
827 {
828 let s = <&str>::deserialize(deserializer)?;
829 Ok(match s {
830 "" | "0" => DefaultFareCategory::NotDefault,
831 "1" => DefaultFareCategory::Default,
832 &_ => {
833 return Err(serde::de::Error::custom(format!(
834 "Invalid value `{s}`, expected 0 or 1"
835 )));
836 }
837 })
838 }
839}
840
841#[derive(Debug, Default, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
843pub enum TicketingType {
844 #[default]
846 #[serde(rename = "0")]
847 Available,
848 #[serde(rename = "1")]
850 Unavailable,
851}