1use std::borrow::Cow;
2
3use chrono::DateTime;
4use chrono::Duration;
5use chrono::FixedOffset;
6#[cfg(feature = "polylines")]
7use geojson::FeatureCollection;
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(untagged)]
14pub enum Location {
15 Address {
16 address: String,
17 latitude: f32,
18 longitude: f32,
19 },
20 Point {
21 #[serde(skip_serializing_if = "Option::is_none")]
22 id: Option<String>,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 name: Option<String>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 poi: Option<bool>,
27 latitude: f32,
28 longitude: f32,
29 },
30}
31
32impl PartialEq for Location {
33 fn eq(&self, other: &Self) -> bool {
34 match (&self, other) {
35 (Location::Address {
36 address: a,
37 ..
38 }, Location::Address {
39 address: b,
40 ..
41 }) => {
42 a == b
43 }
44 (Location::Point {
45 id: Some(a),
46 ..
47 }, Location::Point {
48 id: Some(b),
49 ..
50 }) => {
51 a == b
52 }
53 (_, _) => false,
54 }
55 }
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
59#[serde(tag = "type")]
60#[serde(rename_all = "lowercase")]
61pub enum Place {
62 Stop(Stop),
63 Location(Location),
64}
65
66#[derive(Debug, Default, Clone, Serialize, Deserialize)]
75pub struct Stop {
76 pub id: String,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub name: Option<String>,
79 pub location: Option<Location>,
80 #[serde(skip_serializing_if = "Option::is_none")]
81 pub products: Option<Vec<Product>>,
82 }
84
85impl PartialEq for Stop {
86 fn eq(&self, other: &Self) -> bool {
87 self.id == other.id
88 }
89}
90
91#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
94#[serde(rename_all = "camelCase")]
95pub struct ProductsSelection {
96 pub national_express: Option<bool>,
97 pub national: Option<bool>,
98 pub regional_exp: Option<bool>,
99 pub regional: Option<bool>,
100 pub suburban: Option<bool>,
101 pub bus: Option<bool>,
102 pub ferry: Option<bool>,
103 pub subway: Option<bool>,
104 pub tram: Option<bool>,
105 pub taxi: Option<bool>,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
109#[serde(rename_all = "camelCase")]
110pub struct Product {
111 pub id: Cow<'static, str>,
112 pub mode: Mode,
113 pub bitmasks: Cow<'static, [u16]>,
114 pub name: Cow<'static, str>,
115 pub short: Cow<'static, str>,
116 }
118
119#[derive(Serialize, Debug, Clone, Deserialize, PartialEq, Eq)]
120#[serde(rename_all = "lowercase")]
121pub enum Mode {
122 Train,
123 Bus,
124 Watercraft,
125 Taxi,
126 Walking,
127 Gondola,
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
131pub enum LoyaltyCard {
132 BahnCard25Class1,
133 BahnCard25Class2,
134 BahnCard50Class1,
135 BahnCard50Class2,
136 Vorteilscard,
137 HalbtaxaboRailplus,
138 Halbtaxabo,
139 VoordeelurenaboRailplus,
140 Voordeelurenabo,
141 SHCard,
142 Generalabonnement,
143}
144
145impl LoyaltyCard {
146 pub fn from_id(value: u8) -> Option<Self> {
148 match value {
149 1 => Some(LoyaltyCard::BahnCard25Class1),
150 2 => Some(LoyaltyCard::BahnCard25Class2),
151 3 => Some(LoyaltyCard::BahnCard50Class1),
152 4 => Some(LoyaltyCard::BahnCard50Class2),
153 9 => Some(LoyaltyCard::Vorteilscard),
154 10 => Some(LoyaltyCard::HalbtaxaboRailplus),
155 11 => Some(LoyaltyCard::Halbtaxabo),
156 12 => Some(LoyaltyCard::VoordeelurenaboRailplus),
157 13 => Some(LoyaltyCard::Voordeelurenabo),
158 14 => Some(LoyaltyCard::SHCard),
159 15 => Some(LoyaltyCard::Generalabonnement),
160 _ => None,
161 }
162 }
163
164 pub fn to_id(self) -> u8 {
165 match self {
166 LoyaltyCard::BahnCard25Class1 => 1,
167 LoyaltyCard::BahnCard25Class2 => 2,
168 LoyaltyCard::BahnCard50Class1 => 3,
169 LoyaltyCard::BahnCard50Class2 => 4,
170 LoyaltyCard::Vorteilscard => 9,
171 LoyaltyCard::HalbtaxaboRailplus => 10,
172 LoyaltyCard::Halbtaxabo => 11,
173 LoyaltyCard::VoordeelurenaboRailplus => 12,
174 LoyaltyCard::Voordeelurenabo => 13,
175 LoyaltyCard::SHCard => 14,
176 LoyaltyCard::Generalabonnement => 15,
177 }
178 }
179}
180
181#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
182pub enum TariffClass {
183 First,
184 Second,
185}
186
187#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
188#[serde(rename_all = "lowercase")]
189pub enum Accessibility {
190 r#None,
191 Partial,
192 Complete,
193}
194
195#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
196#[serde(rename_all = "kebab-case")]
197pub enum LoadFactor {
198 LowToMedium,
199 High,
200 VeryHigh,
201 ExceptionallyHigh,
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
205#[serde(rename_all = "camelCase")]
206pub struct Line {
207 pub name: Option<String>,
208 pub fahrt_nr: Option<String>,
209 pub mode: Mode,
210 pub product: Product,
211 pub operator: Option<Operator>,
212 pub product_name: Option<String>,
213}
214
215#[derive(Debug, Serialize, Clone, Deserialize, PartialEq)]
216#[serde(rename_all = "camelCase")]
217pub struct Frequency {
218 #[serde(with = "crate::serialize::duration")]
219 pub minimum: Option<Duration>,
220 #[serde(with = "crate::serialize::duration")]
221 pub maximum: Option<Duration>,
222 pub iterations: Option<u64>,
223}
224
225#[derive(Debug, Serialize, Clone, Deserialize, PartialEq)]
226#[serde(rename_all = "camelCase")]
227pub struct Leg {
228 pub origin: Place,
229 pub destination: Place,
230 pub departure: Option<DateTime<FixedOffset>>,
231 pub planned_departure: Option<DateTime<FixedOffset>>,
232 pub departure_delay: Option<i64>,
233 pub arrival: Option<DateTime<FixedOffset>>,
234 pub planned_arrival: Option<DateTime<FixedOffset>>,
235 pub arrival_delay: Option<i64>,
236 #[serde(skip_serializing_if = "Option::is_none")]
237 pub reachable: Option<bool>,
238 pub trip_id: Option<String>,
239 pub line: Option<Line>,
240 pub direction: Option<String>,
241 pub arrival_platform: Option<String>,
243 pub planned_arrival_platform: Option<String>,
244 pub departure_platform: Option<String>,
245 pub planned_departure_platform: Option<String>,
246 pub frequency: Option<Frequency>,
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub cancelled: Option<bool>,
249 #[serde(skip_serializing_if = "Option::is_none")]
250 pub stopovers: Option<Vec<Stopover>>,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub load_factor: Option<LoadFactor>,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub remarks: Option<Vec<Remark>>,
255 #[cfg(feature = "polylines")]
256 #[serde(skip_serializing_if = "Option::is_none")]
257 pub polyline: Option<FeatureCollection>,
258 #[serde(skip_serializing_if = "Option::is_none")]
259 pub walking: Option<bool>,
260 #[serde(skip_serializing_if = "Option::is_none")]
261 pub transfer: Option<bool>,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 pub distance: Option<u64>,
264}
265
266#[derive(Debug, Serialize, Clone, Deserialize, PartialEq)]
267#[serde(rename_all = "camelCase")]
268pub struct Stopover {
269 pub stop: Place,
270 pub departure: Option<DateTime<FixedOffset>>,
271 pub planned_departure: Option<DateTime<FixedOffset>>,
272 pub departure_delay: Option<i64>,
273 pub arrival: Option<DateTime<FixedOffset>>,
274 pub planned_arrival: Option<DateTime<FixedOffset>>,
275 pub arrival_delay: Option<i64>,
276 pub arrival_platform: Option<String>,
277 pub planned_arrival_platform: Option<String>,
278 pub departure_platform: Option<String>,
279 pub planned_departure_platform: Option<String>,
280 #[serde(skip_serializing_if = "Option::is_none")]
281 pub cancelled: Option<bool>,
282 #[serde(skip_serializing_if = "Option::is_none")]
283 pub remarks: Option<Vec<Remark>>,
284}
285
286#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
287pub struct Price {
288 pub amount: f64,
289 pub currency: String,
290}
291
292#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
293#[serde(rename_all = "camelCase")]
294pub struct Journey {
295 #[serde(skip_serializing_if = "Option::is_none")]
296 pub refresh_token: Option<String>,
297 pub legs: Vec<Leg>,
298 pub price: Option<Price>,
299 }
301
302#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
303pub struct Operator {
304 pub id: String,
305 pub name: String,
306}
307
308#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
309#[serde(rename_all = "lowercase")]
310pub enum RemarkType {
311 Hint,
312 Status,
313}
314
315#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
316pub struct Remark {
317 pub code: String,
318 pub text: String,
319 pub r#type: RemarkType,
320 #[serde(skip_serializing_if = "Option::is_none")]
321 pub summary: Option<String>,
322 #[serde(skip_serializing_if = "Option::is_none")]
323 pub trip_id: Option<String>,
324}