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 trait Model<M: Model<M>> {
21 type K: Copy + Eq + Hash + Serialize + for<'a> Deserialize<'a>;
23
24 fn id(&self) -> M::K;
25
26 fn vec_to_map(data: Vec<M>) -> FxHashMap<M::K, M> {
27 data.into_iter()
28 .fold(FxHashMap::default(), |mut acc, item| {
29 acc.insert(item.id(), item);
30 acc
31 })
32 }
33}
34
35macro_rules! impl_Model {
36 ($m:ty) => {
37 impl Model<$m> for $m {
38 type K = i32;
39
40 fn id(&self) -> Self::K {
41 self.id
42 }
43 }
44 };
45}
46
47#[derive(Debug, Serialize, Deserialize)]
52pub struct Attribute {
53 id: i32,
54 designation: String,
55 stop_scope: i16,
56 main_sorting_priority: i16,
57 secondary_sorting_priority: i16,
58 description: FxHashMap<Language, String>,
59}
60
61impl_Model!(Attribute);
62
63impl Attribute {
64 pub fn new(
65 id: i32,
66 designation: String,
67 stop_scope: i16,
68 main_sorting_priority: i16,
69 secondary_sorting_priority: i16,
70 ) -> Self {
71 Self {
72 id,
73 designation,
74 stop_scope,
75 main_sorting_priority,
76 secondary_sorting_priority,
77 description: FxHashMap::default(),
78 }
79 }
80
81 pub fn set_description(&mut self, language: Language, value: &str) {
84 self.description.insert(language, value.to_string());
85 }
86}
87
88#[derive(Debug, Serialize, Deserialize)]
93pub struct BitField {
94 id: i32,
95 bits: Vec<u8>,
96}
97
98impl_Model!(BitField);
99
100impl BitField {
101 pub fn new(id: i32, bits: Vec<u8>) -> Self {
102 Self { id, bits }
103 }
104
105 pub fn bits(&self) -> &Vec<u8> {
108 &self.bits
109 }
110}
111
112#[derive(Debug, Default, Serialize, Deserialize)]
117pub struct Color {
118 r: i16,
119 g: i16,
120 b: i16,
121}
122
123#[allow(unused)]
124impl Color {
125 pub fn new(r: i16, g: i16, b: i16) -> Self {
126 Self { r, g, b }
127 }
128
129 pub fn r(&self) -> i16 {
132 self.r
133 }
134
135 pub fn g(&self) -> i16 {
136 self.g
137 }
138
139 pub fn b(&self) -> i16 {
140 self.b
141 }
142}
143
144#[derive(Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
149pub enum CoordinateSystem {
150 #[default]
151 LV95,
152 WGS84,
153}
154
155#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize)]
160pub struct Coordinates {
161 coordinate_system: CoordinateSystem,
162 x: f64,
163 y: f64,
164}
165
166#[allow(unused)]
167impl Coordinates {
168 pub fn new(coordinate_system: CoordinateSystem, x: f64, y: f64) -> Self {
169 Self {
170 coordinate_system,
171 x,
172 y,
173 }
174 }
175
176 pub fn easting(&self) -> Option<f64> {
179 match self.coordinate_system {
180 CoordinateSystem::LV95 => Some(self.x),
181 CoordinateSystem::WGS84 => None,
182 }
183 }
184
185 pub fn northing(&self) -> Option<f64> {
186 match self.coordinate_system {
187 CoordinateSystem::LV95 => Some(self.y),
188 CoordinateSystem::WGS84 => None,
189 }
190 }
191
192 pub fn latitude(&self) -> Option<f64> {
193 match self.coordinate_system {
194 CoordinateSystem::WGS84 => Some(self.x),
195 CoordinateSystem::LV95 => None,
196 }
197 }
198
199 pub fn longitude(&self) -> Option<f64> {
200 match self.coordinate_system {
201 CoordinateSystem::WGS84 => Some(self.y),
202 CoordinateSystem::LV95 => None,
203 }
204 }
205}
206
207#[derive(Debug, Serialize, Deserialize)]
212pub struct Direction {
213 id: i32,
214 name: String,
215}
216
217impl_Model!(Direction);
218
219impl Direction {
220 pub fn new(id: i32, name: String) -> Self {
221 Self { id, name }
222 }
223}
224
225#[derive(
230 Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, EnumString, Serialize, Deserialize,
231)]
232pub enum DirectionType {
233 #[default]
234 #[strum(serialize = "R")]
235 Outbound,
236
237 #[strum(serialize = "H")]
238 Return,
239}
240
241#[derive(Debug, Serialize, Deserialize)]
246pub struct Holiday {
247 id: i32,
248 date: NaiveDate,
249 name: FxHashMap<Language, String>,
250}
251
252impl_Model!(Holiday);
253
254impl Holiday {
255 pub fn new(id: i32, date: NaiveDate, name: FxHashMap<Language, String>) -> Self {
256 Self { id, date, name }
257 }
258}
259
260#[derive(Debug, Serialize, Deserialize)]
265pub struct ExchangeTimeAdministration {
266 id: i32,
267 stop_id: Option<i32>, administration_1: String,
269 administration_2: String,
270 duration: i16, }
272
273impl_Model!(ExchangeTimeAdministration);
274
275impl ExchangeTimeAdministration {
276 pub fn new(
277 id: i32,
278 stop_id: Option<i32>,
279 administration_1: String,
280 administration_2: String,
281 duration: i16,
282 ) -> Self {
283 Self {
284 id,
285 stop_id,
286 administration_1,
287 administration_2,
288 duration,
289 }
290 }
291
292 pub fn stop_id(&self) -> Option<i32> {
295 self.stop_id
296 }
297
298 pub fn administration_1(&self) -> &str {
299 &self.administration_1
300 }
301
302 pub fn administration_2(&self) -> &str {
303 &self.administration_2
304 }
305
306 pub fn duration(&self) -> i16 {
307 self.duration
308 }
309}
310
311#[derive(Debug, Serialize, Deserialize)]
316pub struct ExchangeTimeJourney {
317 id: i32,
318 stop_id: i32,
319 journey_id_1: i32,
320 journey_id_2: i32,
321 duration: i16, is_guaranteed: bool,
323 bit_field_id: Option<i32>,
324}
325
326impl_Model!(ExchangeTimeJourney);
327
328impl ExchangeTimeJourney {
329 pub fn new(
330 id: i32,
331 stop_id: i32,
332 journey_id_1: i32,
333 journey_id_2: i32,
334 duration: i16,
335 is_guaranteed: bool,
336 bit_field_id: Option<i32>,
337 ) -> Self {
338 Self {
339 id,
340 stop_id,
341 journey_id_1,
342 journey_id_2,
343 duration,
344 is_guaranteed,
345 bit_field_id,
346 }
347 }
348
349 pub fn stop_id(&self) -> i32 {
352 self.stop_id
353 }
354
355 pub fn journey_id_1(&self) -> i32 {
356 self.journey_id_1
357 }
358
359 pub fn journey_id_2(&self) -> i32 {
360 self.journey_id_2
361 }
362
363 pub fn duration(&self) -> i16 {
364 self.duration
365 }
366
367 pub fn bit_field_id(&self) -> Option<i32> {
368 self.bit_field_id
369 }
370}
371
372#[derive(Debug, Serialize, Deserialize)]
377pub struct ExchangeTimeLine {
378 id: i32,
379 stop_id: Option<i32>,
380 line_1: LineInfo,
381 line_2: LineInfo,
382 duration: i16, is_guaranteed: bool,
384}
385
386impl_Model!(ExchangeTimeLine);
387
388#[derive(Debug, Serialize, Deserialize)]
389pub(crate) struct LineInfo {
390 administration: String,
391 transport_type_id: i32,
392 line_id: Option<String>,
393 direction: Option<DirectionType>,
394}
395
396impl LineInfo {
397 pub(crate) fn new(
398 administration: String,
399 transport_type_id: i32,
400 line_id: Option<String>,
401 direction: Option<DirectionType>,
402 ) -> Self {
403 Self {
404 administration,
405 transport_type_id,
406 line_id,
407 direction,
408 }
409 }
410}
411
412impl ExchangeTimeLine {
413 pub(crate) fn new(
414 id: i32,
415 stop_id: Option<i32>,
416 line_1: LineInfo,
417 line_2: LineInfo,
418 duration: i16,
419 is_guaranteed: bool,
420 ) -> Self {
421 Self {
422 id,
423 stop_id,
424 line_1,
425 line_2,
426 duration,
427 is_guaranteed,
428 }
429 }
430}
431
432#[derive(Debug, Serialize, Deserialize)]
437pub struct InformationText {
438 id: i32,
439 content: FxHashMap<Language, String>,
440}
441
442impl_Model!(InformationText);
443
444impl InformationText {
445 pub fn new(id: i32) -> Self {
446 Self {
447 id,
448 content: FxHashMap::default(),
449 }
450 }
451
452 pub fn set_content(&mut self, language: Language, value: &str) {
455 self.content.insert(language, value.to_string());
456 }
457}
458
459#[derive(Debug, Default, Serialize, Deserialize)]
464pub struct Journey {
465 id: i32,
466 administration: String,
467 metadata: FxHashMap<JourneyMetadataType, Vec<JourneyMetadataEntry>>,
468 route: Vec<JourneyRouteEntry>,
469}
470
471impl_Model!(Journey);
472
473impl Journey {
474 pub fn new(id: i32, administration: String) -> Self {
475 Self {
476 id,
477 administration,
478 metadata: FxHashMap::default(),
479 route: Vec::new(),
480 }
481 }
482
483 pub fn administration(&self) -> &str {
486 &self.administration
487 }
488
489 fn metadata(&self) -> &FxHashMap<JourneyMetadataType, Vec<JourneyMetadataEntry>> {
490 &self.metadata
491 }
492
493 pub fn route(&self) -> &Vec<JourneyRouteEntry> {
494 &self.route
495 }
496
497 pub fn add_metadata_entry(&mut self, k: JourneyMetadataType, v: JourneyMetadataEntry) {
500 self.metadata.entry(k).or_default().push(v);
501 }
502
503 pub fn add_route_entry(&mut self, entry: JourneyRouteEntry) {
504 self.route.push(entry);
505 }
506
507 pub fn bit_field_id(&self) -> Option<i32> {
508 let entry = &self.metadata().get(&JourneyMetadataType::BitField).unwrap()[0];
510 entry.bit_field_id
511 }
512
513 pub fn transport_type_id(&self) -> i32 {
514 let entry = &self
516 .metadata()
517 .get(&JourneyMetadataType::TransportType)
518 .unwrap()[0];
519 entry.resource_id.unwrap()
521 }
522
523 pub fn transport_type<'a>(&'a self, data_storage: &'a DataStorage) -> &'a TransportType {
524 data_storage
525 .transport_types()
526 .find(self.transport_type_id())
527 .unwrap_or_else(|| panic!("Transport type {:?} not found.", self.transport_type_id()))
528 }
529
530 pub fn first_stop_id(&self) -> i32 {
531 self.route.first().unwrap().stop_id()
533 }
534
535 pub fn last_stop_id(&self) -> i32 {
536 self.route.last().unwrap().stop_id()
538 }
539
540 pub fn is_last_stop(&self, stop_id: i32, ignore_loop: bool) -> bool {
541 if ignore_loop && self.first_stop_id() == self.last_stop_id() {
542 false
543 } else {
544 stop_id == self.last_stop_id()
545 }
546 }
547
548 pub fn count_stops(&self, departure_stop_id: i32, arrival_stop_id: i32) -> usize {
549 self.route()
550 .iter()
551 .skip_while(|stop| stop.stop_id() != departure_stop_id)
552 .take_while(|stop| stop.stop_id() != arrival_stop_id)
553 .count()
554 + 1
555 }
556
557 pub fn hash_route(&self, departure_stop_id: i32) -> Option<u64> {
558 let index = self
559 .route
560 .iter()
561 .position(|route_entry| route_entry.stop_id() == departure_stop_id)?;
562
563 let mut hasher = DefaultHasher::new();
564 self.route
565 .iter()
566 .skip(index)
567 .map(|route_entry| route_entry.stop_id())
568 .collect::<BTreeSet<_>>()
569 .hash(&mut hasher);
570 Some(hasher.finish())
571 }
572
573 pub fn departure_time_of(&self, stop_id: i32) -> (NaiveTime, bool) {
576 let route = self.route();
577 let index = route
578 .iter()
579 .position(|route_entry| route_entry.stop_id() == stop_id)
580 .unwrap();
581 let departure_time = route[index].departure_time().unwrap();
582
583 (
584 departure_time,
585 departure_time < route.first().unwrap().departure_time().unwrap(),
587 )
588 }
589
590 pub fn departure_at_of(&self, stop_id: i32, date: NaiveDate) -> NaiveDateTime {
594 match self.departure_time_of(stop_id) {
595 (departure_time, false) => NaiveDateTime::new(date, departure_time),
596 (departure_time, true) => NaiveDateTime::new(add_1_day(date), departure_time),
597 }
598 }
599
600 pub fn departure_at_of_with_origin(
603 &self,
604 stop_id: i32,
605 date: NaiveDate,
606 is_departure_date: bool,
608 origin_stop_id: i32,
609 ) -> NaiveDateTime {
610 let (departure_time, is_next_day) = self.departure_time_of(stop_id);
611 let (_, origin_is_next_day) = if is_departure_date {
612 self.departure_time_of(origin_stop_id)
613 } else {
614 self.arrival_time_of(origin_stop_id)
615 };
616
617 match (is_next_day, origin_is_next_day) {
618 (true, false) => NaiveDateTime::new(add_1_day(date), departure_time),
619 (false, true) => NaiveDateTime::new(sub_1_day(date), departure_time),
620 _ => NaiveDateTime::new(date, departure_time),
621 }
622 }
623
624 pub fn arrival_time_of(&self, stop_id: i32) -> (NaiveTime, bool) {
627 let route = self.route();
628 let index = route
629 .iter()
630 .skip(1)
632 .position(|route_entry| route_entry.stop_id() == stop_id)
633 .map(|i| i + 1)
634 .unwrap();
635 let arrival_time = route[index].arrival_time().unwrap();
636
637 (
638 arrival_time,
639 arrival_time < route.first().unwrap().departure_time().unwrap(),
641 )
642 }
643
644 pub fn arrival_at_of_with_origin(
646 &self,
647 stop_id: i32,
648 date: NaiveDate,
649 is_departure_date: bool,
651 origin_stop_id: i32,
652 ) -> NaiveDateTime {
653 let (arrival_time, is_next_day) = self.arrival_time_of(stop_id);
654 let (_, origin_is_next_day) = if is_departure_date {
655 self.departure_time_of(origin_stop_id)
656 } else {
657 self.arrival_time_of(origin_stop_id)
658 };
659
660 match (is_next_day, origin_is_next_day) {
661 (true, false) => NaiveDateTime::new(add_1_day(date), arrival_time),
662 (false, true) => NaiveDateTime::new(sub_1_day(date), arrival_time),
663 _ => NaiveDateTime::new(date, arrival_time),
664 }
665 }
666
667 pub fn route_section(
669 &self,
670 departure_stop_id: i32,
671 arrival_stop_id: i32,
672 ) -> Vec<&JourneyRouteEntry> {
673 let mut route_iter = self.route().iter();
674
675 for route_entry in route_iter.by_ref() {
676 if route_entry.stop_id() == departure_stop_id {
677 break;
678 }
679 }
680
681 let mut result = Vec::new();
682
683 for route_entry in route_iter {
684 result.push(route_entry);
685
686 if route_entry.stop_id() == arrival_stop_id {
687 break;
688 }
689 }
690
691 result
692 }
693}
694
695#[derive(Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
700pub enum JourneyMetadataType {
701 #[default]
702 Attribute,
703 BitField,
704 Direction,
705 InformationText,
706 Line,
707 ExchangeTimeBoarding,
708 ExchangeTimeDisembarking,
709 TransportType,
710}
711
712#[derive(Debug, Serialize, Deserialize)]
717pub struct JourneyMetadataEntry {
718 from_stop_id: Option<i32>,
719 until_stop_id: Option<i32>,
720 resource_id: Option<i32>,
721 bit_field_id: Option<i32>,
722 departure_time: Option<NaiveTime>,
723 arrival_time: Option<NaiveTime>,
724 extra_field_1: Option<String>,
725 extra_field_2: Option<i32>,
726}
727
728impl JourneyMetadataEntry {
729 #[allow(clippy::too_many_arguments)]
730 pub fn new(
731 from_stop_id: Option<i32>,
732 until_stop_id: Option<i32>,
733 resource_id: Option<i32>,
734 bit_field_id: Option<i32>,
735 departure_time: Option<NaiveTime>,
736 arrival_time: Option<NaiveTime>,
737 extra_field_1: Option<String>,
738 extra_field_2: Option<i32>,
739 ) -> Self {
740 Self {
741 from_stop_id,
742 until_stop_id,
743 resource_id,
744 bit_field_id,
745 departure_time,
746 arrival_time,
747 extra_field_1,
748 extra_field_2,
749 }
750 }
751}
752
753#[derive(Debug, Serialize, Deserialize)]
758pub struct JourneyRouteEntry {
759 stop_id: i32,
760 arrival_time: Option<NaiveTime>,
761 departure_time: Option<NaiveTime>,
762}
763
764impl JourneyRouteEntry {
765 pub fn new(
766 stop_id: i32,
767 arrival_time: Option<NaiveTime>,
768 departure_time: Option<NaiveTime>,
769 ) -> Self {
770 Self {
771 stop_id,
772 arrival_time,
773 departure_time,
774 }
775 }
776
777 pub fn stop_id(&self) -> i32 {
780 self.stop_id
781 }
782
783 pub fn arrival_time(&self) -> &Option<NaiveTime> {
784 &self.arrival_time
785 }
786
787 pub fn departure_time(&self) -> &Option<NaiveTime> {
788 &self.departure_time
789 }
790
791 pub fn stop<'a>(&'a self, data_storage: &'a DataStorage) -> &'a Stop {
794 data_storage
795 .stops()
796 .find(self.stop_id())
797 .unwrap_or_else(|| panic!("Stop {:?} not found.", self.stop_id()))
798 }
799}
800
801#[derive(Debug, Serialize, Deserialize)]
806pub struct JourneyPlatform {
807 journey_id: i32,
808 platform_id: i32,
809 time: Option<NaiveTime>,
810 bit_field_id: Option<i32>,
811}
812
813impl JourneyPlatform {
814 pub fn new(
815 journey_id: i32,
816 platform_id: i32,
817 time: Option<NaiveTime>,
818 bit_field_id: Option<i32>,
819 ) -> Self {
820 Self {
821 journey_id,
822 platform_id,
823 time,
824 bit_field_id,
825 }
826 }
827}
828
829impl Model<JourneyPlatform> for JourneyPlatform {
830 type K = (i32, i32);
831
832 fn id(&self) -> Self::K {
833 (self.journey_id, self.platform_id)
834 }
835}
836
837#[derive(
842 Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, EnumString, Serialize, Deserialize,
843)]
844pub enum Language {
845 #[default]
846 #[strum(serialize = "deu")]
847 German,
848
849 #[strum(serialize = "fra")]
850 French,
851
852 #[strum(serialize = "ita")]
853 Italian,
854
855 #[strum(serialize = "eng")]
856 English,
857}
858
859#[derive(Debug, Default, Serialize, Deserialize)]
864pub struct Line {
865 id: i32,
866 name: String,
867 short_name: String,
868 long_name: String,
869 text_color: Color,
870 background_color: Color,
871}
872
873impl_Model!(Line);
874
875impl Line {
876 pub fn new(id: i32, name: String) -> Self {
877 Self {
878 id,
879 name,
880 short_name: String::default(),
881 long_name: String::default(),
882 text_color: Color::default(),
883 background_color: Color::default(),
884 }
885 }
886
887 pub fn set_short_name(&mut self, value: String) {
890 self.short_name = value;
891 }
892
893 pub fn set_long_name(&mut self, value: String) {
894 self.long_name = value;
895 }
896
897 pub fn set_text_color(&mut self, value: Color) {
898 self.text_color = value;
899 }
900
901 pub fn set_background_color(&mut self, value: Color) {
902 self.background_color = value;
903 }
904}
905
906#[derive(Debug, Serialize, Deserialize)]
911pub struct Platform {
912 id: i32,
913 name: String,
914 sectors: Option<String>,
915 stop_id: i32,
916 sloid: String,
917 lv95_coordinates: Coordinates,
918 wgs84_coordinates: Coordinates,
919}
920
921impl_Model!(Platform);
922
923impl Platform {
924 pub fn new(id: i32, name: String, sectors: Option<String>, stop_id: i32) -> Self {
925 Self {
926 id,
927 name,
928 sectors,
929 stop_id,
930 sloid: String::default(),
931 lv95_coordinates: Coordinates::default(),
932 wgs84_coordinates: Coordinates::default(),
933 }
934 }
935
936 pub fn set_sloid(&mut self, value: String) {
939 self.sloid = value;
940 }
941
942 pub fn set_lv95_coordinates(&mut self, value: Coordinates) {
943 self.lv95_coordinates = value;
944 }
945
946 pub fn set_wgs84_coordinates(&mut self, value: Coordinates) {
947 self.wgs84_coordinates = value;
948 }
949}
950
951#[derive(Debug, Serialize, Deserialize)]
956pub struct Stop {
957 id: i32,
958 name: String,
959 long_name: Option<String>,
960 abbreviation: Option<String>,
961 synonyms: Option<Vec<String>>,
962 lv95_coordinates: Option<Coordinates>,
963 wgs84_coordinates: Option<Coordinates>,
964 exchange_priority: i16,
965 exchange_flag: i16,
966 exchange_time: Option<(i16, i16)>, restrictions: i16,
968 sloid: String,
969 boarding_areas: Vec<String>,
970}
971
972impl_Model!(Stop);
973
974impl Stop {
975 pub fn new(
976 id: i32,
977 name: String,
978 long_name: Option<String>,
979 abbreviation: Option<String>,
980 synonyms: Option<Vec<String>>,
981 ) -> Self {
982 Self {
983 id,
984 name,
985 long_name,
986 abbreviation,
987 synonyms,
988 lv95_coordinates: None,
989 wgs84_coordinates: None,
990 exchange_priority: 8, exchange_flag: 0,
992 exchange_time: None,
993 restrictions: 0,
994 sloid: String::default(),
995 boarding_areas: Vec::new(),
996 }
997 }
998
999 pub fn name(&self) -> &str {
1002 &self.name
1003 }
1004
1005 pub fn lv95_coordinates(&self) -> Option<Coordinates> {
1006 self.lv95_coordinates
1007 }
1008
1009 pub fn set_lv95_coordinates(&mut self, value: Coordinates) {
1010 self.lv95_coordinates = Some(value);
1011 }
1012
1013 pub fn wgs84_coordinates(&self) -> Option<Coordinates> {
1014 self.wgs84_coordinates
1015 }
1016
1017 pub fn set_wgs84_coordinates(&mut self, value: Coordinates) {
1018 self.wgs84_coordinates = Some(value);
1019 }
1020
1021 pub fn set_exchange_priority(&mut self, value: i16) {
1022 self.exchange_priority = value;
1023 }
1024
1025 pub fn exchange_flag(&self) -> i16 {
1026 self.exchange_flag
1027 }
1028
1029 pub fn set_exchange_flag(&mut self, value: i16) {
1030 self.exchange_flag = value;
1031 }
1032
1033 pub fn exchange_time(&self) -> Option<(i16, i16)> {
1034 self.exchange_time
1035 }
1036
1037 pub fn set_exchange_time(&mut self, value: Option<(i16, i16)>) {
1038 self.exchange_time = value;
1039 }
1040
1041 pub fn set_restrictions(&mut self, value: i16) {
1042 self.restrictions = value;
1043 }
1044
1045 pub fn set_sloid(&mut self, value: String) {
1046 self.sloid = value;
1047 }
1048
1049 pub fn add_boarding_area(&mut self, value: String) {
1052 self.boarding_areas.push(value);
1053 }
1054
1055 pub fn can_be_used_as_exchange_point(&self) -> bool {
1056 self.exchange_flag() != 0
1057 }
1058}
1059
1060#[derive(Debug, Default, Serialize, Deserialize)]
1065pub struct StopConnection {
1066 id: i32,
1067 stop_id_1: i32,
1068 stop_id_2: i32,
1069 duration: i16, attribute: i32,
1071}
1072
1073impl_Model!(StopConnection);
1074
1075impl StopConnection {
1076 pub fn new(id: i32, stop_id_1: i32, stop_id_2: i32, duration: i16) -> Self {
1077 Self {
1078 id,
1079 stop_id_1,
1080 stop_id_2,
1081 duration,
1082 attribute: 0,
1083 }
1084 }
1085
1086 pub fn stop_id_1(&self) -> i32 {
1089 self.stop_id_1
1090 }
1091
1092 pub fn stop_id_2(&self) -> i32 {
1093 self.stop_id_2
1094 }
1095
1096 pub fn duration(&self) -> i16 {
1097 self.duration
1098 }
1099
1100 pub fn set_attribute(&mut self, value: i32) {
1101 self.attribute = value;
1102 }
1103}
1104
1105#[derive(Debug, Serialize, Deserialize)]
1110pub struct ThroughService {
1111 id: i32,
1112 journey_1_id: i32,
1113 journey_1_stop_id: i32, journey_2_id: i32,
1115 journey_2_stop_id: Option<i32>, bit_field_id: i32,
1117}
1118
1119impl_Model!(ThroughService);
1120
1121impl ThroughService {
1122 pub fn new(
1123 id: i32,
1124 journey_1_id: i32,
1125 journey_1_stop_id: i32,
1126 journey_2_id: i32,
1127 journey_2_stop_id: Option<i32>,
1128 bit_field_id: i32,
1129 ) -> Self {
1130 Self {
1131 id,
1132 journey_1_id,
1133 journey_1_stop_id,
1134 journey_2_id,
1135 journey_2_stop_id,
1136 bit_field_id,
1137 }
1138 }
1139}
1140
1141#[derive(Debug, Serialize, Deserialize)]
1146pub struct TimetableMetadataEntry {
1147 id: i32,
1148 key: String,
1149 value: String,
1150}
1151
1152impl_Model!(TimetableMetadataEntry);
1153
1154impl TimetableMetadataEntry {
1155 pub fn new(id: i32, key: String, value: String) -> Self {
1156 Self { id, key, value }
1157 }
1158
1159 pub fn key(&self) -> &str {
1162 &self.key
1163 }
1164
1165 pub fn value(&self) -> &str {
1166 &self.value
1167 }
1168
1169 #[allow(non_snake_case)]
1171 pub fn value_as_NaiveDate(&self) -> NaiveDate {
1172 NaiveDate::parse_from_str(self.value(), "%Y-%m-%d").unwrap()
1173 }
1174}
1175
1176#[derive(Debug, Serialize, Deserialize)]
1181pub struct TransportCompany {
1182 id: i32,
1183 short_name: FxHashMap<Language, String>,
1184 long_name: FxHashMap<Language, String>,
1185 full_name: FxHashMap<Language, String>,
1186 administrations: Vec<String>,
1187}
1188
1189impl_Model!(TransportCompany);
1190
1191impl TransportCompany {
1192 pub fn new(id: i32, administrations: Vec<String>) -> Self {
1193 Self {
1194 id,
1195 short_name: FxHashMap::default(),
1196 long_name: FxHashMap::default(),
1197 full_name: FxHashMap::default(),
1198 administrations,
1199 }
1200 }
1201
1202 pub fn set_short_name(&mut self, language: Language, value: &str) {
1205 self.short_name.insert(language, value.to_string());
1206 }
1207
1208 pub fn set_long_name(&mut self, language: Language, value: &str) {
1209 self.long_name.insert(language, value.to_string());
1210 }
1211
1212 pub fn set_full_name(&mut self, language: Language, value: &str) {
1213 self.full_name.insert(language, value.to_string());
1214 }
1215}
1216
1217#[derive(Debug, Default, Serialize, Deserialize)]
1222pub struct TransportType {
1223 id: i32,
1224 designation: String,
1225 product_class_id: i16,
1226 tarrif_group: String,
1227 output_control: i16,
1228 short_name: String,
1229 surchage: i16,
1230 flag: String,
1231 product_class_name: FxHashMap<Language, String>,
1232 category_name: FxHashMap<Language, String>,
1233}
1234
1235impl_Model!(TransportType);
1236
1237impl TransportType {
1238 #[allow(clippy::too_many_arguments)]
1239 pub fn new(
1240 id: i32,
1241 designation: String,
1242 product_class_id: i16,
1243 tarrif_group: String,
1244 output_control: i16,
1245 short_name: String,
1246 surchage: i16,
1247 flag: String,
1248 ) -> Self {
1249 Self {
1250 id,
1251 designation,
1252 product_class_id,
1253 tarrif_group,
1254 output_control,
1255 short_name,
1256 surchage,
1257 flag,
1258 product_class_name: FxHashMap::default(),
1259 category_name: FxHashMap::default(),
1260 }
1261 }
1262
1263 pub fn designation(&self) -> &str {
1266 &self.designation
1267 }
1268
1269 pub fn product_class_id(&self) -> i16 {
1270 self.product_class_id
1271 }
1272
1273 pub fn set_product_class_name(&mut self, language: Language, value: &str) {
1274 self.product_class_name.insert(language, value.to_string());
1275 }
1276
1277 pub fn set_category_name(&mut self, language: Language, value: &str) {
1278 self.category_name.insert(language, value.to_string());
1279 }
1280}
1281
1282#[derive(Clone, Copy, Debug, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
1287#[allow(non_camel_case_types)]
1288pub enum Version {
1289 V_5_40_41_2_0_4,
1290 V_5_40_41_2_0_5,
1291 V_5_40_41_2_0_6,
1292 V_5_40_41_2_0_7,
1293}