1use std::{
2 collections::BTreeSet,
3 hash::{DefaultHasher, Hash, Hasher},
4};
5
6use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
7use rustc_hash::FxHashMap;
8use serde::{Deserialize, Serialize};
9use strum_macros::{self, Display, EnumString};
10
11use crate::{
12 storage::DataStorage,
13 utils::{add_1_day, sub_1_day},
14};
15
16pub(crate) type JourneyId = (i32, String); pub trait Model<M: Model<M>> {
23 type K: Copy + Eq + Hash + Serialize + for<'a> Deserialize<'a>;
25
26 fn id(&self) -> M::K;
27}
28
29macro_rules! impl_Model {
30 ($m:ty) => {
31 impl Model<$m> for $m {
32 type K = i32;
33
34 fn id(&self) -> Self::K {
35 self.id
36 }
37 }
38 };
39}
40
41#[derive(Debug, Serialize, Deserialize)]
46pub struct Attribute {
47 id: i32,
48 designation: String,
49 stop_scope: i16,
50 main_sorting_priority: i16,
51 secondary_sorting_priority: i16,
52 description: FxHashMap<Language, String>,
53}
54
55impl_Model!(Attribute);
56
57impl Attribute {
58 pub fn new(
59 id: i32,
60 designation: String,
61 stop_scope: i16,
62 main_sorting_priority: i16,
63 secondary_sorting_priority: i16,
64 ) -> Self {
65 Self {
66 id,
67 designation,
68 stop_scope,
69 main_sorting_priority,
70 secondary_sorting_priority,
71 description: FxHashMap::default(),
72 }
73 }
74
75 pub fn set_description(&mut self, language: Language, value: &str) {
78 self.description.insert(language, value.to_string());
79 }
80}
81
82#[derive(Debug, Serialize, Deserialize)]
87pub struct BitField {
88 id: i32,
89 bits: Vec<u8>,
90}
91
92impl_Model!(BitField);
93
94impl BitField {
95 pub fn new(id: i32, bits: Vec<u8>) -> Self {
96 Self { id, bits }
97 }
98
99 pub fn bits(&self) -> &Vec<u8> {
102 &self.bits
103 }
104}
105
106#[derive(Debug, Default, Serialize, Deserialize)]
111pub struct Color {
112 r: i16,
113 g: i16,
114 b: i16,
115}
116
117#[allow(unused)]
118impl Color {
119 pub fn new(r: i16, g: i16, b: i16) -> Self {
120 Self { r, g, b }
121 }
122
123 pub fn r(&self) -> i16 {
126 self.r
127 }
128
129 pub fn g(&self) -> i16 {
130 self.g
131 }
132
133 pub fn b(&self) -> i16 {
134 self.b
135 }
136}
137
138#[derive(Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
143pub enum CoordinateSystem {
144 #[default]
145 LV95,
146 WGS84,
147}
148
149#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
154pub struct Coordinates {
155 coordinate_system: CoordinateSystem,
156 x: f64,
157 y: f64,
158}
159
160#[allow(unused)]
161impl Coordinates {
162 pub fn new(coordinate_system: CoordinateSystem, x: f64, y: f64) -> Self {
163 Self {
164 coordinate_system,
165 x,
166 y,
167 }
168 }
169
170 pub fn easting(&self) -> Option<f64> {
173 match self.coordinate_system {
174 CoordinateSystem::LV95 => Some(self.x),
175 CoordinateSystem::WGS84 => None,
176 }
177 }
178
179 pub fn northing(&self) -> Option<f64> {
180 match self.coordinate_system {
181 CoordinateSystem::LV95 => Some(self.y),
182 CoordinateSystem::WGS84 => None,
183 }
184 }
185
186 pub fn latitude(&self) -> Option<f64> {
187 match self.coordinate_system {
188 CoordinateSystem::WGS84 => Some(self.x),
189 CoordinateSystem::LV95 => None,
190 }
191 }
192
193 pub fn longitude(&self) -> Option<f64> {
194 match self.coordinate_system {
195 CoordinateSystem::WGS84 => Some(self.y),
196 CoordinateSystem::LV95 => None,
197 }
198 }
199}
200
201#[derive(Debug, Serialize, Deserialize)]
206pub struct Direction {
207 id: i32,
208 name: String,
209}
210
211impl_Model!(Direction);
212
213impl Direction {
214 pub fn new(id: i32, name: String) -> Self {
215 Self { id, name }
216 }
217}
218
219#[derive(
224 Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, EnumString, Serialize, Deserialize,
225)]
226pub enum DirectionType {
227 #[default]
228 #[strum(serialize = "R")]
229 Outbound,
230
231 #[strum(serialize = "H")]
232 Return,
233}
234
235#[derive(Debug, Serialize, Deserialize)]
240pub struct Holiday {
241 id: i32,
242 date: NaiveDate,
243 name: FxHashMap<Language, String>,
244}
245
246impl_Model!(Holiday);
247
248impl Holiday {
249 pub fn new(id: i32, date: NaiveDate, name: FxHashMap<Language, String>) -> Self {
250 Self { id, date, name }
251 }
252}
253
254#[derive(Debug, Serialize, Deserialize)]
259pub struct ExchangeTimeAdministration {
260 id: i32,
261 stop_id: Option<i32>, administration_1: String,
263 administration_2: String,
264 duration: i16, }
266
267impl_Model!(ExchangeTimeAdministration);
268
269impl ExchangeTimeAdministration {
270 pub fn new(
271 id: i32,
272 stop_id: Option<i32>,
273 administration_1: String,
274 administration_2: String,
275 duration: i16,
276 ) -> Self {
277 Self {
278 id,
279 stop_id,
280 administration_1,
281 administration_2,
282 duration,
283 }
284 }
285
286 pub fn stop_id(&self) -> Option<i32> {
289 self.stop_id
290 }
291
292 pub fn administration_1(&self) -> &str {
293 &self.administration_1
294 }
295
296 pub fn administration_2(&self) -> &str {
297 &self.administration_2
298 }
299
300 pub fn duration(&self) -> i16 {
301 self.duration
302 }
303}
304
305#[derive(Debug, Serialize, Deserialize)]
310pub struct ExchangeTimeJourney {
311 id: i32,
312 stop_id: i32,
313 journey_legacy_id_1: i32,
314 administration_1: String,
315 journey_legacy_id_2: i32,
316 administration_2: String,
317 duration: i16, is_guaranteed: bool,
319 bit_field_id: Option<i32>,
320}
321
322impl_Model!(ExchangeTimeJourney);
323
324impl ExchangeTimeJourney {
325 pub fn new(
326 id: i32,
327 stop_id: i32,
328 (journey_legacy_id_1, administration_1): JourneyId,
329 (journey_legacy_id_2, administration_2): JourneyId,
330 duration: i16,
331 is_guaranteed: bool,
332 bit_field_id: Option<i32>,
333 ) -> Self {
334 Self {
335 id,
336 stop_id,
337 journey_legacy_id_1,
338 administration_1,
339 journey_legacy_id_2,
340 administration_2,
341 duration,
342 is_guaranteed,
343 bit_field_id,
344 }
345 }
346
347 pub fn stop_id(&self) -> i32 {
350 self.stop_id
351 }
352
353 pub fn journey_legacy_id_1(&self) -> i32 {
354 self.journey_legacy_id_1
355 }
356
357 pub fn administration_1(&self) -> &str {
358 &self.administration_1
359 }
360
361 pub fn journey_legacy_id_2(&self) -> i32 {
362 self.journey_legacy_id_2
363 }
364
365 pub fn administration_2(&self) -> &str {
366 &self.administration_2
367 }
368
369 pub fn duration(&self) -> i16 {
370 self.duration
371 }
372
373 pub fn bit_field_id(&self) -> Option<i32> {
374 self.bit_field_id
375 }
376}
377
378#[derive(Debug, Serialize, Deserialize)]
383pub struct ExchangeTimeLine {
384 id: i32,
385 stop_id: Option<i32>,
386 line_1: LineInfo,
387 line_2: LineInfo,
388 duration: i16, is_guaranteed: bool,
390}
391
392impl_Model!(ExchangeTimeLine);
393
394#[derive(Debug, Serialize, Deserialize)]
395pub(crate) struct LineInfo {
396 administration: String,
397 transport_type_id: i32,
398 line_id: Option<String>,
399 direction: Option<DirectionType>,
400}
401
402impl LineInfo {
403 pub(crate) fn new(
404 administration: String,
405 transport_type_id: i32,
406 line_id: Option<String>,
407 direction: Option<DirectionType>,
408 ) -> Self {
409 Self {
410 administration,
411 transport_type_id,
412 line_id,
413 direction,
414 }
415 }
416}
417
418impl ExchangeTimeLine {
419 pub(crate) fn new(
420 id: i32,
421 stop_id: Option<i32>,
422 line_1: LineInfo,
423 line_2: LineInfo,
424 duration: i16,
425 is_guaranteed: bool,
426 ) -> Self {
427 Self {
428 id,
429 stop_id,
430 line_1,
431 line_2,
432 duration,
433 is_guaranteed,
434 }
435 }
436}
437
438#[derive(Debug, Serialize, Deserialize)]
443pub struct InformationText {
444 id: i32,
445 content: FxHashMap<Language, String>,
446}
447
448impl_Model!(InformationText);
449
450impl InformationText {
451 pub fn new(id: i32) -> Self {
452 Self {
453 id,
454 content: FxHashMap::default(),
455 }
456 }
457
458 pub fn set_content(&mut self, language: Language, value: &str) {
461 self.content.insert(language, value.to_string());
462 }
463}
464
465#[derive(Debug, Default, Serialize, Deserialize)]
470pub struct Journey {
471 id: i32,
472 legacy_id: i32,
473 administration: String,
474 metadata: FxHashMap<JourneyMetadataType, Vec<JourneyMetadataEntry>>,
475 route: Vec<JourneyRouteEntry>,
476}
477
478impl_Model!(Journey);
479
480impl Journey {
481 pub fn new(id: i32, legacy_id: i32, administration: String) -> Self {
482 Self {
483 id,
484 legacy_id,
485 administration,
486 metadata: FxHashMap::default(),
487 route: Vec::new(),
488 }
489 }
490
491 pub fn administration(&self) -> &str {
494 &self.administration
495 }
496
497 pub fn legacy_id(&self) -> i32 {
498 self.legacy_id
499 }
500
501 fn metadata(&self) -> &FxHashMap<JourneyMetadataType, Vec<JourneyMetadataEntry>> {
502 &self.metadata
503 }
504
505 pub fn route(&self) -> &Vec<JourneyRouteEntry> {
506 &self.route
507 }
508
509 pub fn add_metadata_entry(&mut self, k: JourneyMetadataType, v: JourneyMetadataEntry) {
512 self.metadata.entry(k).or_default().push(v);
513 }
514
515 pub fn add_route_entry(&mut self, entry: JourneyRouteEntry) {
516 self.route.push(entry);
517 }
518
519 pub fn bit_field_id(&self) -> Option<i32> {
520 let entry = &self.metadata().get(&JourneyMetadataType::BitField).unwrap()[0];
522 entry.bit_field_id
523 }
524
525 pub fn transport_type_id(&self) -> i32 {
526 let entry = &self
528 .metadata()
529 .get(&JourneyMetadataType::TransportType)
530 .unwrap()[0];
531 entry.resource_id.unwrap()
533 }
534
535 pub fn transport_type<'a>(&'a self, data_storage: &'a DataStorage) -> &'a TransportType {
536 data_storage
537 .transport_types()
538 .find(self.transport_type_id())
539 .unwrap_or_else(|| panic!("Transport type {:?} not found.", self.transport_type_id()))
540 }
541
542 pub fn first_stop_id(&self) -> i32 {
543 self.route.first().unwrap().stop_id()
545 }
546
547 pub fn last_stop_id(&self) -> i32 {
548 self.route.last().unwrap().stop_id()
550 }
551
552 pub fn is_last_stop(&self, stop_id: i32, ignore_loop: bool) -> bool {
553 if ignore_loop && self.first_stop_id() == self.last_stop_id() {
554 false
555 } else {
556 stop_id == self.last_stop_id()
557 }
558 }
559
560 pub fn count_stops(&self, departure_stop_id: i32, arrival_stop_id: i32) -> usize {
561 self.route()
562 .iter()
563 .skip_while(|stop| stop.stop_id() != departure_stop_id)
564 .take_while(|stop| stop.stop_id() != arrival_stop_id)
565 .count()
566 + 1
567 }
568
569 pub fn hash_route(&self, departure_stop_id: i32) -> Option<u64> {
570 let index = self
571 .route
572 .iter()
573 .position(|route_entry| route_entry.stop_id() == departure_stop_id)?;
574
575 let mut hasher = DefaultHasher::new();
576 self.route
577 .iter()
578 .skip(index)
579 .map(|route_entry| route_entry.stop_id())
580 .collect::<BTreeSet<_>>()
581 .hash(&mut hasher);
582 Some(hasher.finish())
583 }
584
585 pub fn departure_time_of(&self, stop_id: i32) -> (NaiveTime, bool) {
588 let route = self.route();
589 let index = route
590 .iter()
591 .position(|route_entry| route_entry.stop_id() == stop_id)
592 .unwrap();
593 let departure_time = route[index].departure_time().unwrap();
594
595 (
596 departure_time,
597 departure_time < route.first().unwrap().departure_time().unwrap(),
599 )
600 }
601
602 pub fn departure_at_of(&self, stop_id: i32, date: NaiveDate) -> NaiveDateTime {
606 match self.departure_time_of(stop_id) {
607 (departure_time, false) => NaiveDateTime::new(date, departure_time),
608 (departure_time, true) => NaiveDateTime::new(add_1_day(date), departure_time),
609 }
610 }
611
612 pub fn departure_at_of_with_origin(
615 &self,
616 stop_id: i32,
617 date: NaiveDate,
618 is_departure_date: bool,
620 origin_stop_id: i32,
621 ) -> NaiveDateTime {
622 let (departure_time, is_next_day) = self.departure_time_of(stop_id);
623 let (_, origin_is_next_day) = if is_departure_date {
624 self.departure_time_of(origin_stop_id)
625 } else {
626 self.arrival_time_of(origin_stop_id)
627 };
628
629 match (is_next_day, origin_is_next_day) {
630 (true, false) => NaiveDateTime::new(add_1_day(date), departure_time),
631 (false, true) => NaiveDateTime::new(sub_1_day(date), departure_time),
632 _ => NaiveDateTime::new(date, departure_time),
633 }
634 }
635
636 pub fn arrival_time_of(&self, stop_id: i32) -> (NaiveTime, bool) {
639 let route = self.route();
640 let index = route
641 .iter()
642 .skip(1)
644 .position(|route_entry| route_entry.stop_id() == stop_id)
645 .map(|i| i + 1)
646 .unwrap();
647 let arrival_time = route[index].arrival_time().unwrap();
648
649 (
650 arrival_time,
651 arrival_time < route.first().unwrap().departure_time().unwrap(),
653 )
654 }
655
656 pub fn arrival_at_of_with_origin(
658 &self,
659 stop_id: i32,
660 date: NaiveDate,
661 is_departure_date: bool,
663 origin_stop_id: i32,
664 ) -> NaiveDateTime {
665 let (arrival_time, is_next_day) = self.arrival_time_of(stop_id);
666 let (_, origin_is_next_day) = if is_departure_date {
667 self.departure_time_of(origin_stop_id)
668 } else {
669 self.arrival_time_of(origin_stop_id)
670 };
671
672 match (is_next_day, origin_is_next_day) {
673 (true, false) => NaiveDateTime::new(add_1_day(date), arrival_time),
674 (false, true) => NaiveDateTime::new(sub_1_day(date), arrival_time),
675 _ => NaiveDateTime::new(date, arrival_time),
676 }
677 }
678
679 pub fn route_section(
681 &self,
682 departure_stop_id: i32,
683 arrival_stop_id: i32,
684 ) -> Vec<&JourneyRouteEntry> {
685 let mut route_iter = self.route().iter();
686
687 for route_entry in route_iter.by_ref() {
688 if route_entry.stop_id() == departure_stop_id {
689 break;
690 }
691 }
692
693 let mut result = Vec::new();
694
695 for route_entry in route_iter {
696 result.push(route_entry);
697
698 if route_entry.stop_id() == arrival_stop_id {
699 break;
700 }
701 }
702
703 result
704 }
705}
706
707#[derive(Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
712pub enum JourneyMetadataType {
713 #[default]
714 Attribute,
715 BitField,
716 Direction,
717 InformationText,
718 Line,
719 ExchangeTimeBoarding,
720 ExchangeTimeDisembarking,
721 TransportType,
722}
723
724#[derive(Debug, Serialize, Deserialize)]
729pub struct JourneyMetadataEntry {
730 from_stop_id: Option<i32>,
731 until_stop_id: Option<i32>,
732 resource_id: Option<i32>,
733 bit_field_id: Option<i32>,
734 departure_time: Option<NaiveTime>,
735 arrival_time: Option<NaiveTime>,
736 extra_field_1: Option<String>,
737 extra_field_2: Option<i32>,
738}
739
740impl JourneyMetadataEntry {
741 #[allow(clippy::too_many_arguments)]
742 pub fn new(
743 from_stop_id: Option<i32>,
744 until_stop_id: Option<i32>,
745 resource_id: Option<i32>,
746 bit_field_id: Option<i32>,
747 departure_time: Option<NaiveTime>,
748 arrival_time: Option<NaiveTime>,
749 extra_field_1: Option<String>,
750 extra_field_2: Option<i32>,
751 ) -> Self {
752 Self {
753 from_stop_id,
754 until_stop_id,
755 resource_id,
756 bit_field_id,
757 departure_time,
758 arrival_time,
759 extra_field_1,
760 extra_field_2,
761 }
762 }
763}
764
765#[derive(Debug, Serialize, Deserialize)]
770pub struct JourneyRouteEntry {
771 stop_id: i32,
772 arrival_time: Option<NaiveTime>,
773 departure_time: Option<NaiveTime>,
774}
775
776impl JourneyRouteEntry {
777 pub fn new(
778 stop_id: i32,
779 arrival_time: Option<NaiveTime>,
780 departure_time: Option<NaiveTime>,
781 ) -> Self {
782 Self {
783 stop_id,
784 arrival_time,
785 departure_time,
786 }
787 }
788
789 pub fn stop_id(&self) -> i32 {
792 self.stop_id
793 }
794
795 pub fn arrival_time(&self) -> &Option<NaiveTime> {
796 &self.arrival_time
797 }
798
799 pub fn departure_time(&self) -> &Option<NaiveTime> {
800 &self.departure_time
801 }
802
803 pub fn stop<'a>(&'a self, data_storage: &'a DataStorage) -> &'a Stop {
806 data_storage
807 .stops()
808 .find(self.stop_id())
809 .unwrap_or_else(|| panic!("Stop {:?} not found.", self.stop_id()))
810 }
811}
812
813#[derive(Debug, Serialize, Deserialize)]
818pub struct JourneyPlatform {
819 journey_legacy_id: i32,
820 administration: String,
821 platform_id: i32,
822 time: Option<NaiveTime>,
823 bit_field_id: Option<i32>,
824}
825
826impl JourneyPlatform {
827 pub fn new(
828 journey_legacy_id: i32,
829 administration: String,
830 platform_id: i32,
831 time: Option<NaiveTime>,
832 bit_field_id: Option<i32>,
833 ) -> Self {
834 Self {
835 journey_legacy_id,
836 administration,
837 platform_id,
838 time,
839 bit_field_id,
840 }
841 }
842}
843
844impl Model<JourneyPlatform> for JourneyPlatform {
845 type K = (i32, i32);
846
847 fn id(&self) -> Self::K {
848 (self.journey_legacy_id, self.platform_id)
849 }
850}
851
852#[derive(
857 Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, EnumString, Serialize, Deserialize,
858)]
859pub enum Language {
860 #[default]
861 #[strum(serialize = "deu", serialize = "DE")]
862 German,
863
864 #[strum(serialize = "fra", serialize = "FR")]
865 French,
866
867 #[strum(serialize = "ita", serialize = "IT")]
868 Italian,
869
870 #[strum(serialize = "eng", serialize = "EN")]
871 English,
872}
873
874#[derive(Debug, Default, Serialize, Deserialize)]
879pub struct Line {
880 id: i32,
881 name: String,
882 short_name: String,
883 long_name: String,
884 internal_designation: String,
885 text_color: Color,
886 background_color: Color,
887}
888
889impl_Model!(Line);
890
891impl Line {
892 pub fn new(id: i32, name: String) -> Self {
893 Self {
894 id,
895 name,
896 short_name: String::default(),
897 long_name: String::default(),
898 internal_designation: String::default(),
899 text_color: Color::default(),
900 background_color: Color::default(),
901 }
902 }
903
904 pub fn set_short_name(&mut self, value: String) {
907 self.short_name = value;
908 }
909
910 pub fn set_long_name(&mut self, value: String) {
911 self.long_name = value;
912 }
913
914 pub fn set_internal_designation(&mut self, value: String) {
915 self.internal_designation = value;
916 }
917
918 pub fn set_text_color(&mut self, value: Color) {
919 self.text_color = value;
920 }
921
922 pub fn set_background_color(&mut self, value: Color) {
923 self.background_color = value;
924 }
925}
926
927#[derive(Debug, Serialize, Deserialize)]
932pub struct Platform {
933 id: i32,
934 name: String,
935 sectors: Option<String>,
936 stop_id: i32,
937 sloid: String,
938 lv95_coordinates: Coordinates,
939 wgs84_coordinates: Coordinates,
940}
941
942impl_Model!(Platform);
943
944impl Platform {
945 pub fn new(id: i32, name: String, sectors: Option<String>, stop_id: i32) -> Self {
946 Self {
947 id,
948 name,
949 sectors,
950 stop_id,
951 sloid: String::default(),
952 lv95_coordinates: Coordinates::default(),
953 wgs84_coordinates: Coordinates::default(),
954 }
955 }
956
957 pub fn set_sloid(&mut self, value: String) {
960 self.sloid = value;
961 }
962
963 pub fn set_lv95_coordinates(&mut self, value: Coordinates) {
964 self.lv95_coordinates = value;
965 }
966
967 pub fn set_wgs84_coordinates(&mut self, value: Coordinates) {
968 self.wgs84_coordinates = value;
969 }
970}
971
972#[derive(Debug, Serialize, Deserialize)]
977pub struct Stop {
978 id: i32,
979 name: String,
980 long_name: Option<String>,
981 abbreviation: Option<String>,
982 synonyms: Option<Vec<String>>,
983 lv95_coordinates: Option<Coordinates>,
984 wgs84_coordinates: Option<Coordinates>,
985 exchange_priority: i16,
986 exchange_flag: i16,
987 exchange_time: Option<(i16, i16)>, restrictions: i16,
989 sloid: String,
990 boarding_areas: Vec<String>,
991}
992
993impl_Model!(Stop);
994
995impl Stop {
996 pub fn new(
997 id: i32,
998 name: String,
999 long_name: Option<String>,
1000 abbreviation: Option<String>,
1001 synonyms: Option<Vec<String>>,
1002 ) -> Self {
1003 Self {
1004 id,
1005 name,
1006 long_name,
1007 abbreviation,
1008 synonyms,
1009 lv95_coordinates: None,
1010 wgs84_coordinates: None,
1011 exchange_priority: 8, exchange_flag: 0,
1013 exchange_time: None,
1014 restrictions: 0,
1015 sloid: String::default(),
1016 boarding_areas: Vec::new(),
1017 }
1018 }
1019
1020 pub fn name(&self) -> &str {
1023 &self.name
1024 }
1025
1026 pub fn lv95_coordinates(&self) -> Option<Coordinates> {
1027 self.lv95_coordinates
1028 }
1029
1030 pub fn set_lv95_coordinates(&mut self, value: Coordinates) {
1031 self.lv95_coordinates = Some(value);
1032 }
1033
1034 pub fn wgs84_coordinates(&self) -> Option<Coordinates> {
1035 self.wgs84_coordinates
1036 }
1037
1038 pub fn set_wgs84_coordinates(&mut self, value: Coordinates) {
1039 self.wgs84_coordinates = Some(value);
1040 }
1041
1042 pub fn set_exchange_priority(&mut self, value: i16) {
1043 self.exchange_priority = value;
1044 }
1045
1046 pub fn exchange_flag(&self) -> i16 {
1047 self.exchange_flag
1048 }
1049
1050 pub fn set_exchange_flag(&mut self, value: i16) {
1051 self.exchange_flag = value;
1052 }
1053
1054 pub fn exchange_time(&self) -> Option<(i16, i16)> {
1055 self.exchange_time
1056 }
1057
1058 pub fn set_exchange_time(&mut self, value: Option<(i16, i16)>) {
1059 self.exchange_time = value;
1060 }
1061
1062 pub fn set_restrictions(&mut self, value: i16) {
1063 self.restrictions = value;
1064 }
1065
1066 pub fn set_sloid(&mut self, value: String) {
1067 self.sloid = value;
1068 }
1069
1070 pub fn add_boarding_area(&mut self, value: String) {
1073 self.boarding_areas.push(value);
1074 }
1075
1076 pub fn can_be_used_as_exchange_point(&self) -> bool {
1077 self.exchange_flag() != 0
1078 }
1079}
1080
1081#[derive(Debug, Default, Serialize, Deserialize)]
1086pub struct StopConnection {
1087 id: i32,
1088 stop_id_1: i32,
1089 stop_id_2: i32,
1090 duration: i16, attribute: i32,
1092}
1093
1094impl_Model!(StopConnection);
1095
1096impl StopConnection {
1097 pub fn new(id: i32, stop_id_1: i32, stop_id_2: i32, duration: i16) -> Self {
1098 Self {
1099 id,
1100 stop_id_1,
1101 stop_id_2,
1102 duration,
1103 attribute: 0,
1104 }
1105 }
1106
1107 pub fn stop_id_1(&self) -> i32 {
1110 self.stop_id_1
1111 }
1112
1113 pub fn stop_id_2(&self) -> i32 {
1114 self.stop_id_2
1115 }
1116
1117 pub fn duration(&self) -> i16 {
1118 self.duration
1119 }
1120
1121 pub fn set_attribute(&mut self, value: i32) {
1122 self.attribute = value;
1123 }
1124}
1125
1126#[derive(Debug, Serialize, Deserialize)]
1131pub struct ThroughService {
1132 id: i32,
1133 journey_1_id: JourneyId,
1134 journey_1_stop_id: i32, journey_2_id: JourneyId,
1136 journey_2_stop_id: i32, bit_field_id: i32,
1138}
1139
1140impl_Model!(ThroughService);
1141
1142impl ThroughService {
1143 pub fn new(
1144 id: i32,
1145 journey_1_id: JourneyId,
1146 journey_1_stop_id: i32,
1147 journey_2_id: JourneyId,
1148 journey_2_stop_id: i32,
1149 bit_field_id: i32,
1150 ) -> Self {
1151 Self {
1152 id,
1153 journey_1_id,
1154 journey_1_stop_id,
1155 journey_2_id,
1156 journey_2_stop_id,
1157 bit_field_id,
1158 }
1159 }
1160
1161 pub fn journey_1_id(&self) -> &JourneyId {
1162 &self.journey_1_id
1163 }
1164
1165 pub fn journey_1_stop_id(&self) -> i32 {
1166 self.journey_1_stop_id
1167 }
1168
1169 pub fn journey_2_id(&self) -> &JourneyId {
1170 &self.journey_2_id
1171 }
1172
1173 pub fn journey_2_stop_id(&self) -> i32 {
1174 self.journey_2_stop_id
1175 }
1176
1177 pub fn bit_field_id(&self) -> i32 {
1178 self.bit_field_id
1179 }
1180}
1181
1182#[derive(Debug, Serialize, Deserialize)]
1187pub struct TimetableMetadataEntry {
1188 id: i32,
1189 key: String,
1190 value: String,
1191}
1192
1193impl_Model!(TimetableMetadataEntry);
1194
1195impl TimetableMetadataEntry {
1196 pub fn new(id: i32, key: String, value: String) -> Self {
1197 Self { id, key, value }
1198 }
1199
1200 pub fn key(&self) -> &str {
1203 &self.key
1204 }
1205
1206 pub fn value(&self) -> &str {
1207 &self.value
1208 }
1209
1210 #[allow(non_snake_case)]
1212 pub fn value_as_NaiveDate(&self) -> NaiveDate {
1213 NaiveDate::parse_from_str(self.value(), "%Y-%m-%d").unwrap()
1214 }
1215}
1216
1217#[derive(Debug, Serialize, Deserialize)]
1222pub struct TransportCompany {
1223 id: i32,
1224 short_name: FxHashMap<Language, String>,
1225 long_name: FxHashMap<Language, String>,
1226 full_name: FxHashMap<Language, String>,
1227 administrations: Vec<String>,
1228}
1229
1230impl_Model!(TransportCompany);
1231
1232impl TransportCompany {
1233 pub fn new(id: i32) -> Self {
1234 Self {
1235 id,
1236 short_name: FxHashMap::default(),
1237 long_name: FxHashMap::default(),
1238 full_name: FxHashMap::default(),
1239 administrations: Vec::new(),
1240 }
1241 }
1242
1243 pub fn set_administrations(&mut self, administrations: Vec<String>) {
1246 self.administrations = administrations;
1247 }
1248
1249 pub fn set_short_name(&mut self, language: Language, value: &str) {
1250 self.short_name.insert(language, value.to_string());
1251 }
1252
1253 pub fn set_long_name(&mut self, language: Language, value: &str) {
1254 self.long_name.insert(language, value.to_string());
1255 }
1256
1257 pub fn set_full_name(&mut self, language: Language, value: &str) {
1258 self.full_name.insert(language, value.to_string());
1259 }
1260}
1261
1262#[derive(Debug, Default, Serialize, Deserialize)]
1267pub struct TransportType {
1268 id: i32,
1269 designation: String,
1270 product_class_id: i16,
1271 tariff_group: String,
1272 output_control: i16,
1273 short_name: String,
1274 surcharge: i16,
1275 flag: String,
1276 product_class_name: FxHashMap<Language, String>,
1277 category_name: FxHashMap<Language, String>,
1278}
1279
1280impl_Model!(TransportType);
1281
1282impl TransportType {
1283 #[allow(clippy::too_many_arguments)]
1284 pub fn new(
1285 id: i32,
1286 designation: String,
1287 product_class_id: i16,
1288 tariff_group: String,
1289 output_control: i16,
1290 short_name: String,
1291 surcharge: i16,
1292 flag: String,
1293 ) -> Self {
1294 Self {
1295 id,
1296 designation,
1297 product_class_id,
1298 tariff_group,
1299 output_control,
1300 short_name,
1301 surcharge,
1302 flag,
1303 product_class_name: FxHashMap::default(),
1304 category_name: FxHashMap::default(),
1305 }
1306 }
1307
1308 pub fn designation(&self) -> &str {
1311 &self.designation
1312 }
1313
1314 pub fn product_class_id(&self) -> i16 {
1315 self.product_class_id
1316 }
1317
1318 pub fn set_product_class_name(&mut self, language: Language, value: &str) {
1319 self.product_class_name.insert(language, value.to_string());
1320 }
1321
1322 pub fn set_category_name(&mut self, language: Language, value: &str) {
1323 self.category_name.insert(language, value.to_string());
1324 }
1325}
1326
1327#[derive(Clone, Copy, Debug, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
1332#[allow(non_camel_case_types)]
1333pub enum Version {
1334 V_5_40_41_2_0_4,
1335 V_5_40_41_2_0_5,
1336 V_5_40_41_2_0_6,
1337 V_5_40_41_2_0_7,
1338}