use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
#[derive(Debug, Serialize, Eq, PartialEq, Hash)]
pub enum ObjectType {
Agency,
Stop,
Route,
Trip,
Calendar,
Shape,
Fare,
Pathway,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum LocationType {
#[default]
StopPoint,
StopArea,
StationEntrance,
GenericNode,
BoardingArea,
Unknown(i16),
}
fn serialize_i16_as_str<S: Serializer>(s: S, value: i16) -> Result<S::Ok, S::Error> {
s.serialize_str(&value.to_string())
}
impl<'de> Deserialize<'de> for LocationType {
fn deserialize<D>(deserializer: D) -> Result<LocationType, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => LocationType::StopPoint,
"1" => LocationType::StopArea,
"2" => LocationType::StationEntrance,
"3" => LocationType::GenericNode,
"4" => LocationType::BoardingArea,
s => LocationType::Unknown(s.parse().map_err(|_| {
serde::de::Error::custom(format!(
"invalid value for LocationType, must be an integer: {s}"
))
})?),
})
}
}
impl Serialize for LocationType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_i16_as_str(
serializer,
match self {
LocationType::StopPoint => 0,
LocationType::StopArea => 1,
LocationType::StationEntrance => 2,
LocationType::GenericNode => 3,
LocationType::BoardingArea => 4,
LocationType::Unknown(i) => *i,
},
)
}
}
#[derive(Debug, Clone, derive_more::TryFrom, Copy, PartialEq, Eq, Hash)]
#[repr(i16)]
#[try_from(repr)]
pub enum ExtendedRouteType {
Railway = 100,
HighSpeedRail = 101,
LongDistanceTrains = 102,
InterRegionalRail = 103,
CarTransportRail = 104,
SleeperRail = 105,
RegionalRail = 106,
TouristRailway = 107,
RailShuttleWithinComplex = 108,
SuburbanRailway = 109,
ReplacementRail = 110,
SpecialRail = 111,
LorryTransportRail = 112,
OtherRail = 113,
CrossCountryRail = 114,
VehicleTransportRail = 115,
RackAndPinionRailway = 116,
AdditionalRail = 117,
Coach = 200,
InternationalCoach = 201,
NationalCoach = 202,
ShuttleCoach = 203,
RegionalCoach = 204,
SpecialCoach = 205,
SightseeingCoach = 206,
TouristCoach = 207,
CommuterCoach = 208,
OtherCoach = 209,
UrbanRailway = 400,
Metro = 401,
Underground = 402,
UrbanRailwayServiceDetail = 403,
OtherUrbanRailway = 404,
Monorail = 405,
Bus = 700,
RegionalBus = 701,
ExpressBus = 702,
StoppingBus = 703,
LocalBus = 704,
NightBus = 705,
PostBus = 706,
SpecialNeedsBus = 707,
MobilityBus = 708,
MobilityBusForRegisteredDisabled = 709,
SightseeingBus = 710,
ShuttleBus = 711,
SchoolBus = 712,
SchoolAndPublicServiceBus = 713,
RailReplacementBus = 714,
DemandAndResponseBus = 715,
OtherBus = 716,
Trolleybus = 800,
Tram = 900,
CityTram = 901,
LocalTram = 902,
RegionalTram = 903,
SightseeingTram = 904,
ShuttleTram = 905,
OtherTram = 906,
WaterTransport = 1000,
Air = 1100,
Ferry = 1200,
AerialLift = 1300,
Telecabin = 1301,
CableCar = 1302,
Elevator = 1303,
ChairLift = 1304,
DragLift = 1305,
SmallTelecabin = 1306,
OtherTelecabin = 1307,
Funicular = 1400,
Taxi = 1500,
CommunalTaxi = 1501,
WaterTaxi = 1502,
RailTaxi = 1503,
BikeTaxi = 1504,
LicensedTaxi = 1505,
PrivateHireServiceVehicle = 1506,
OtherTaxi = 1507,
MiscellaneousService = 1700,
HorseDrawnCarriage = 1702,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum RouteType {
Tramway,
Subway,
Rail,
#[default]
Bus,
Ferry,
CableCar,
Gondola,
Funicular,
Extended(ExtendedRouteType),
Other(i16),
}
impl ExtendedRouteType {
pub fn to_standard_route_type(&self) -> RouteType {
let int = *self as i16;
let hundreds = int / 100;
match hundreds {
1 => RouteType::Rail,
4 => RouteType::Subway,
2 | 7 | 8 => RouteType::Bus,
9 => RouteType::Tramway,
10 | 12 => RouteType::Ferry,
13 => RouteType::Gondola,
14 => RouteType::Funicular,
_ => RouteType::Extended(*self),
}
}
}
impl<'de> Deserialize<'de> for RouteType {
fn deserialize<D>(deserializer: D) -> Result<RouteType, D::Error>
where
D: Deserializer<'de>,
{
let i = i16::deserialize(deserializer)?;
if let Ok(ert) = ExtendedRouteType::try_from(i) {
return Ok(RouteType::Extended(ert));
}
Ok(match i {
0 => RouteType::Tramway,
1 => RouteType::Subway,
2 => RouteType::Rail,
3 => RouteType::Bus,
4 => RouteType::Ferry,
5 => RouteType::CableCar,
6 => RouteType::Gondola,
7 => RouteType::Funicular,
_ => RouteType::Other(i),
})
}
}
impl Serialize for RouteType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_i16(match self {
RouteType::Tramway => 0,
RouteType::Subway => 1,
RouteType::Rail => 2,
RouteType::Bus => 3,
RouteType::Ferry => 4,
RouteType::CableCar => 5,
RouteType::Gondola => 6,
RouteType::Funicular => 7,
RouteType::Extended(ert) => *ert as i16,
RouteType::Other(i) => *i,
})
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum PickupDropOffType {
#[default]
Regular,
NotAvailable,
ArrangeByPhone,
CoordinateWithDriver,
Unknown(i16),
}
impl<'de> Deserialize<'de> for PickupDropOffType {
fn deserialize<D>(deserializer: D) -> Result<PickupDropOffType, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => PickupDropOffType::Regular,
"1" => PickupDropOffType::NotAvailable,
"2" => PickupDropOffType::ArrangeByPhone,
"3" => PickupDropOffType::CoordinateWithDriver,
s => PickupDropOffType::Unknown(s.parse().map_err(|_| {
serde::de::Error::custom(format!(
"invalid value for PickupDropOffType, must be an integer: {s}"
))
})?),
})
}
}
impl Serialize for PickupDropOffType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_i16_as_str(
serializer,
match self {
PickupDropOffType::Regular => 0,
PickupDropOffType::NotAvailable => 1,
PickupDropOffType::ArrangeByPhone => 2,
PickupDropOffType::CoordinateWithDriver => 3,
PickupDropOffType::Unknown(i) => *i,
},
)
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum ContinuousPickupDropOff {
Continuous,
#[default]
NotAvailable,
ArrangeByPhone,
CoordinateWithDriver,
Unknown(i16),
}
impl Serialize for ContinuousPickupDropOff {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_i16_as_str(
serializer,
match self {
ContinuousPickupDropOff::Continuous => 0,
ContinuousPickupDropOff::NotAvailable => 1,
ContinuousPickupDropOff::ArrangeByPhone => 2,
ContinuousPickupDropOff::CoordinateWithDriver => 3,
ContinuousPickupDropOff::Unknown(i) => *i,
},
)
}
}
impl<'de> Deserialize<'de> for ContinuousPickupDropOff {
fn deserialize<D>(deserializer: D) -> Result<ContinuousPickupDropOff, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"0" => ContinuousPickupDropOff::Continuous,
"" | "1" => ContinuousPickupDropOff::NotAvailable,
"2" => ContinuousPickupDropOff::ArrangeByPhone,
"3" => ContinuousPickupDropOff::CoordinateWithDriver,
s => ContinuousPickupDropOff::Unknown(s.parse().map_err(|_| {
serde::de::Error::custom(format!(
"invalid value for ContinuousPickupDropOff, must be an integer: {s}"
))
})?),
})
}
}
#[derive(Debug, Default, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TimepointType {
#[serde(rename = "0")]
Approximate = 0,
#[default]
#[serde(rename = "1")]
Exact = 1,
}
impl<'de> Deserialize<'de> for TimepointType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
match s {
"" | "1" => Ok(Self::Exact),
"0" => Ok(Self::Approximate),
v => Err(serde::de::Error::custom(format!(
"invalid value for timepoint: {v}"
))),
}
}
}
#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Availability {
#[default]
InformationNotAvailable,
Available,
NotAvailable,
Unknown(i16),
}
impl<'de> Deserialize<'de> for Availability {
fn deserialize<D>(deserializer: D) -> Result<Availability, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => Availability::InformationNotAvailable,
"1" => Availability::Available,
"2" => Availability::NotAvailable,
s => Availability::Unknown(s.parse().map_err(|_| {
serde::de::Error::custom(format!(
"invalid value for Availability, must be an integer: {s}"
))
})?),
})
}
}
impl Serialize for Availability {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_i16_as_str(
serializer,
match self {
Availability::InformationNotAvailable => 0,
Availability::Available => 1,
Availability::NotAvailable => 2,
Availability::Unknown(i) => *i,
},
)
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum Exception {
#[serde(rename = "1")]
Added,
#[serde(rename = "2")]
Deleted,
}
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
pub enum DirectionType {
#[serde(rename = "0")]
Outbound,
#[serde(rename = "1")]
Inbound,
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum BikesAllowedType {
#[default]
NoBikeInfo,
AtLeastOneBike,
NoBikesAllowed,
Unknown(i16),
}
impl<'de> Deserialize<'de> for BikesAllowedType {
fn deserialize<D>(deserializer: D) -> Result<BikesAllowedType, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => BikesAllowedType::NoBikeInfo,
"1" => BikesAllowedType::AtLeastOneBike,
"2" => BikesAllowedType::NoBikesAllowed,
s => BikesAllowedType::Unknown(s.parse().map_err(|_| {
serde::de::Error::custom(format!(
"invalid value for BikeAllowedType, must be an integer: {s}"
))
})?),
})
}
}
impl Serialize for BikesAllowedType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_i16_as_str(
serializer,
match self {
BikesAllowedType::NoBikeInfo => 0,
BikesAllowedType::AtLeastOneBike => 1,
BikesAllowedType::NoBikesAllowed => 2,
BikesAllowedType::Unknown(i) => *i,
},
)
}
}
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
pub enum PaymentMethod {
#[serde(rename = "0")]
Aboard,
#[serde(rename = "1")]
PreBoarding,
}
#[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
pub enum ExactTimes {
FrequencyBased = 0,
ScheduleBased = 1,
}
impl<'de> Deserialize<'de> for ExactTimes {
fn deserialize<D>(deserializer: D) -> Result<ExactTimes, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => ExactTimes::FrequencyBased,
"1" => ExactTimes::ScheduleBased,
&_ => {
return Err(serde::de::Error::custom(format!(
"Invalid value `{s}`, expected 0 or 1"
)));
}
})
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Transfers {
#[default]
Unlimited,
NoTransfer,
UniqueTransfer,
TwoTransfers,
Other(i16),
}
impl<'de> Deserialize<'de> for Transfers {
fn deserialize<D>(deserializer: D) -> Result<Transfers, D::Error>
where
D: Deserializer<'de>,
{
let i = Option::<i16>::deserialize(deserializer)?;
Ok(match i {
Some(0) => Transfers::NoTransfer,
Some(1) => Transfers::UniqueTransfer,
Some(2) => Transfers::TwoTransfers,
Some(a) => Transfers::Other(a),
None => Transfers::default(),
})
}
}
impl Serialize for Transfers {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Transfers::NoTransfer => serialize_i16_as_str(serializer, 0),
Transfers::UniqueTransfer => serialize_i16_as_str(serializer, 1),
Transfers::TwoTransfers => serialize_i16_as_str(serializer, 2),
Transfers::Other(a) => serialize_i16_as_str(serializer, *a),
Transfers::Unlimited => serializer.serialize_none(),
}
}
}
#[derive(Debug, Serialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum TransferType {
#[serde(rename = "0")]
#[default]
Recommended,
#[serde(rename = "1")]
Timed,
#[serde(rename = "2")]
MinTime,
#[serde(rename = "3")]
Impossible,
#[serde(rename = "4")]
StayOnBoard,
#[serde(rename = "5")]
MustAlight,
}
impl<'de> Deserialize<'de> for TransferType {
fn deserialize<D>(deserializer: D) -> Result<TransferType, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => TransferType::Recommended,
"1" => TransferType::Timed,
"2" => TransferType::MinTime,
"3" => TransferType::Impossible,
"4" => TransferType::StayOnBoard,
"5" => TransferType::MustAlight,
s => {
return Err(serde::de::Error::custom(format!(
"Invalid value `{s}`, expected 0, 1, 2, 3, 4, 5"
)));
}
})
}
}
#[derive(Debug, Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum PathwayMode {
#[serde(rename = "1")]
#[default]
Walkway,
#[serde(rename = "2")]
Stairs,
#[serde(rename = "3")]
MovingSidewalk,
#[serde(rename = "4")]
Escalator,
#[serde(rename = "5")]
Elevator,
#[serde(rename = "6")]
FareGate,
#[serde(rename = "7")]
ExitGate,
}
#[derive(Debug, Serialize, Deserialize, Default, Copy, Clone, PartialEq, Eq, Hash)]
pub enum PathwayDirectionType {
#[serde(rename = "0")]
#[default]
Unidirectional,
#[serde(rename = "1")]
Bidirectional,
}
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
pub enum FareMediaType {
#[serde(rename = "0")]
None,
#[serde(rename = "1")]
PhysicalPaperTicket,
#[serde(rename = "2")]
PhysicalTransitCard,
#[serde(rename = "3")]
CEmv,
#[serde(rename = "4")]
MobileApp,
}
#[derive(Debug, Serialize, Copy, Clone, PartialEq, Eq, Hash)]
pub enum DefaultFareCategory {
NotDefault = 0,
Default = 1,
}
impl<'de> Deserialize<'de> for DefaultFareCategory {
fn deserialize<D>(deserializer: D) -> Result<DefaultFareCategory, D::Error>
where
D: Deserializer<'de>,
{
let s = <&str>::deserialize(deserializer)?;
Ok(match s {
"" | "0" => DefaultFareCategory::NotDefault,
"1" => DefaultFareCategory::Default,
&_ => {
return Err(serde::de::Error::custom(format!(
"Invalid value `{s}`, expected 0 or 1"
)));
}
})
}
}
#[derive(Debug, Default, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
pub enum TicketingType {
#[default]
#[serde(rename = "0")]
Available,
#[serde(rename = "1")]
Unavailable,
}