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) -> f64 {
179 assert!(self.coordinate_system == CoordinateSystem::LV95);
180 self.x
181 }
182
183 pub fn northing(&self) -> f64 {
184 assert!(self.coordinate_system == CoordinateSystem::LV95);
185 self.y
186 }
187
188 pub fn latitude(&self) -> f64 {
189 assert!(self.coordinate_system == CoordinateSystem::WGS84);
190 self.x
191 }
192
193 pub fn longitude(&self) -> f64 {
194 assert!(self.coordinate_system == CoordinateSystem::WGS84);
195 self.y
196 }
197}
198
199#[derive(Debug, Serialize, Deserialize)]
204pub struct Direction {
205 id: i32,
206 name: String,
207}
208
209impl_Model!(Direction);
210
211impl Direction {
212 pub fn new(id: i32, name: String) -> Self {
213 Self { id, name }
214 }
215}
216
217#[derive(
222 Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, EnumString, Serialize, Deserialize,
223)]
224pub enum DirectionType {
225 #[default]
226 #[strum(serialize = "R")]
227 Outbound,
228
229 #[strum(serialize = "H")]
230 Return,
231}
232
233#[derive(Debug, Serialize, Deserialize)]
238pub struct Holiday {
239 id: i32,
240 date: NaiveDate,
241 name: FxHashMap<Language, String>,
242}
243
244impl_Model!(Holiday);
245
246impl Holiday {
247 pub fn new(id: i32, date: NaiveDate, name: FxHashMap<Language, String>) -> Self {
248 Self { id, date, name }
249 }
250}
251
252#[derive(Debug, Serialize, Deserialize)]
257pub struct ExchangeTimeAdministration {
258 id: i32,
259 stop_id: Option<i32>, administration_1: String,
261 administration_2: String,
262 duration: i16, }
264
265impl_Model!(ExchangeTimeAdministration);
266
267impl ExchangeTimeAdministration {
268 pub fn new(
269 id: i32,
270 stop_id: Option<i32>,
271 administration_1: String,
272 administration_2: String,
273 duration: i16,
274 ) -> Self {
275 Self {
276 id,
277 stop_id,
278 administration_1,
279 administration_2,
280 duration,
281 }
282 }
283
284 pub fn stop_id(&self) -> Option<i32> {
287 self.stop_id
288 }
289
290 pub fn administration_1(&self) -> &str {
291 &self.administration_1
292 }
293
294 pub fn administration_2(&self) -> &str {
295 &self.administration_2
296 }
297
298 pub fn duration(&self) -> i16 {
299 self.duration
300 }
301}
302
303#[derive(Debug, Serialize, Deserialize)]
308pub struct ExchangeTimeJourney {
309 id: i32,
310 stop_id: i32,
311 journey_id_1: i32,
312 journey_id_2: i32,
313 duration: i16, is_guaranteed: bool,
315 bit_field_id: Option<i32>,
316}
317
318impl_Model!(ExchangeTimeJourney);
319
320impl ExchangeTimeJourney {
321 pub fn new(
322 id: i32,
323 stop_id: i32,
324 journey_id_1: i32,
325 journey_id_2: i32,
326 duration: i16,
327 is_guaranteed: bool,
328 bit_field_id: Option<i32>,
329 ) -> Self {
330 Self {
331 id,
332 stop_id,
333 journey_id_1,
334 journey_id_2,
335 duration,
336 is_guaranteed,
337 bit_field_id,
338 }
339 }
340
341 pub fn stop_id(&self) -> i32 {
344 self.stop_id
345 }
346
347 pub fn journey_id_1(&self) -> i32 {
348 self.journey_id_1
349 }
350
351 pub fn journey_id_2(&self) -> i32 {
352 self.journey_id_2
353 }
354
355 pub fn duration(&self) -> i16 {
356 self.duration
357 }
358
359 pub fn bit_field_id(&self) -> Option<i32> {
360 self.bit_field_id
361 }
362}
363
364#[derive(Debug, Serialize, Deserialize)]
369pub struct ExchangeTimeLine {
370 id: i32,
371 stop_id: Option<i32>,
372 line_1: LineInfo,
373 line_2: LineInfo,
374 duration: i16, is_guaranteed: bool,
376}
377
378impl_Model!(ExchangeTimeLine);
379
380#[derive(Debug, Serialize, Deserialize)]
381pub(crate) struct LineInfo {
382 administration: String,
383 transport_type_id: i32,
384 line_id: Option<String>,
385 direction: Option<DirectionType>,
386}
387
388impl LineInfo {
389 pub(crate) fn new(
390 administration: String,
391 transport_type_id: i32,
392 line_id: Option<String>,
393 direction: Option<DirectionType>,
394 ) -> Self {
395 Self {
396 administration,
397 transport_type_id,
398 line_id,
399 direction,
400 }
401 }
402}
403
404impl ExchangeTimeLine {
405 pub(crate) fn new(
406 id: i32,
407 stop_id: Option<i32>,
408 line_1: LineInfo,
409 line_2: LineInfo,
410 duration: i16,
411 is_guaranteed: bool,
412 ) -> Self {
413 Self {
414 id,
415 stop_id,
416 line_1,
417 line_2,
418 duration,
419 is_guaranteed,
420 }
421 }
422}
423
424#[derive(Debug, Serialize, Deserialize)]
429pub struct InformationText {
430 id: i32,
431 content: FxHashMap<Language, String>,
432}
433
434impl_Model!(InformationText);
435
436impl InformationText {
437 pub fn new(id: i32) -> Self {
438 Self {
439 id,
440 content: FxHashMap::default(),
441 }
442 }
443
444 pub fn set_content(&mut self, language: Language, value: &str) {
447 self.content.insert(language, value.to_string());
448 }
449}
450
451#[derive(Debug, Default, Serialize, Deserialize)]
456pub struct Journey {
457 id: i32,
458 administration: String,
459 metadata: FxHashMap<JourneyMetadataType, Vec<JourneyMetadataEntry>>,
460 route: Vec<JourneyRouteEntry>,
461}
462
463impl_Model!(Journey);
464
465impl Journey {
466 pub fn new(id: i32, administration: String) -> Self {
467 Self {
468 id,
469 administration,
470 metadata: FxHashMap::default(),
471 route: Vec::new(),
472 }
473 }
474
475 pub fn administration(&self) -> &str {
478 &self.administration
479 }
480
481 fn metadata(&self) -> &FxHashMap<JourneyMetadataType, Vec<JourneyMetadataEntry>> {
482 &self.metadata
483 }
484
485 pub fn route(&self) -> &Vec<JourneyRouteEntry> {
486 &self.route
487 }
488
489 pub fn add_metadata_entry(&mut self, k: JourneyMetadataType, v: JourneyMetadataEntry) {
492 self.metadata.entry(k).or_default().push(v);
493 }
494
495 pub fn add_route_entry(&mut self, entry: JourneyRouteEntry) {
496 self.route.push(entry);
497 }
498
499 pub fn bit_field_id(&self) -> Option<i32> {
500 let entry = &self.metadata().get(&JourneyMetadataType::BitField).unwrap()[0];
502 entry.bit_field_id
503 }
504
505 pub fn transport_type_id(&self) -> i32 {
506 let entry = &self
508 .metadata()
509 .get(&JourneyMetadataType::TransportType)
510 .unwrap()[0];
511 entry.resource_id.unwrap()
513 }
514
515 pub fn transport_type<'a>(&'a self, data_storage: &'a DataStorage) -> &TransportType {
516 data_storage
517 .transport_types()
518 .find(self.transport_type_id())
519 .unwrap_or_else(|| panic!("Transport type {:?} not found.", self.transport_type_id()))
520 }
521
522 pub fn first_stop_id(&self) -> i32 {
523 self.route.first().unwrap().stop_id()
525 }
526
527 pub fn last_stop_id(&self) -> i32 {
528 self.route.last().unwrap().stop_id()
530 }
531
532 pub fn is_last_stop(&self, stop_id: i32, ignore_loop: bool) -> bool {
533 if ignore_loop && self.first_stop_id() == self.last_stop_id() {
534 false
535 } else {
536 stop_id == self.last_stop_id()
537 }
538 }
539
540 pub fn count_stops(&self, departure_stop_id: i32, arrival_stop_id: i32) -> usize {
541 self.route()
542 .iter()
543 .skip_while(|stop| stop.stop_id() != departure_stop_id)
544 .take_while(|stop| stop.stop_id() != arrival_stop_id)
545 .count()
546 + 1
547 }
548
549 pub fn hash_route(&self, departure_stop_id: i32) -> Option<u64> {
550 let index = self
551 .route
552 .iter()
553 .position(|route_entry| route_entry.stop_id() == departure_stop_id)?;
554
555 let mut hasher = DefaultHasher::new();
556 self.route
557 .iter()
558 .skip(index)
559 .map(|route_entry| route_entry.stop_id())
560 .collect::<BTreeSet<_>>()
561 .hash(&mut hasher);
562 Some(hasher.finish())
563 }
564
565 pub fn departure_time_of(&self, stop_id: i32) -> (NaiveTime, bool) {
568 let route = self.route();
569 let index = route
570 .iter()
571 .position(|route_entry| route_entry.stop_id() == stop_id)
572 .unwrap();
573 let departure_time = route[index].departure_time().unwrap();
574
575 (
576 departure_time,
577 departure_time < route.first().unwrap().departure_time().unwrap(),
579 )
580 }
581
582 pub fn departure_at_of(&self, stop_id: i32, date: NaiveDate) -> NaiveDateTime {
586 match self.departure_time_of(stop_id) {
587 (departure_time, false) => NaiveDateTime::new(date, departure_time),
588 (departure_time, true) => NaiveDateTime::new(add_1_day(date), departure_time),
589 }
590 }
591
592 pub fn departure_at_of_with_origin(
595 &self,
596 stop_id: i32,
597 date: NaiveDate,
598 is_departure_date: bool,
600 origin_stop_id: i32,
601 ) -> NaiveDateTime {
602 let (departure_time, is_next_day) = self.departure_time_of(stop_id);
603 let (_, origin_is_next_day) = if is_departure_date {
604 self.departure_time_of(origin_stop_id)
605 } else {
606 self.arrival_time_of(origin_stop_id)
607 };
608
609 match (is_next_day, origin_is_next_day) {
610 (true, false) => NaiveDateTime::new(add_1_day(date), departure_time),
611 (false, true) => NaiveDateTime::new(sub_1_day(date), departure_time),
612 _ => NaiveDateTime::new(date, departure_time),
613 }
614 }
615
616 pub fn arrival_time_of(&self, stop_id: i32) -> (NaiveTime, bool) {
619 let route = self.route();
620 let index = route
621 .iter()
622 .skip(1)
624 .position(|route_entry| route_entry.stop_id() == stop_id)
625 .map(|i| i + 1)
626 .unwrap();
627 let arrival_time = route[index].arrival_time().unwrap();
628
629 (
630 arrival_time,
631 arrival_time < route.first().unwrap().departure_time().unwrap(),
633 )
634 }
635
636 pub fn arrival_at_of_with_origin(
638 &self,
639 stop_id: i32,
640 date: NaiveDate,
641 is_departure_date: bool,
643 origin_stop_id: i32,
644 ) -> NaiveDateTime {
645 let (arrival_time, is_next_day) = self.arrival_time_of(stop_id);
646 let (_, origin_is_next_day) = if is_departure_date {
647 self.departure_time_of(origin_stop_id)
648 } else {
649 self.arrival_time_of(origin_stop_id)
650 };
651
652 match (is_next_day, origin_is_next_day) {
653 (true, false) => NaiveDateTime::new(add_1_day(date), arrival_time),
654 (false, true) => NaiveDateTime::new(sub_1_day(date), arrival_time),
655 _ => NaiveDateTime::new(date, arrival_time),
656 }
657 }
658
659 pub fn route_section(
661 &self,
662 departure_stop_id: i32,
663 arrival_stop_id: i32,
664 ) -> Vec<&JourneyRouteEntry> {
665 let mut route_iter = self.route().iter();
666
667 for route_entry in route_iter.by_ref() {
668 if route_entry.stop_id() == departure_stop_id {
669 break;
670 }
671 }
672
673 let mut result = Vec::new();
674
675 for route_entry in route_iter {
676 result.push(route_entry);
677
678 if route_entry.stop_id() == arrival_stop_id {
679 break;
680 }
681 }
682
683 result
684 }
685}
686
687#[derive(Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
692pub enum JourneyMetadataType {
693 #[default]
694 Attribute,
695 BitField,
696 Direction,
697 InformationText,
698 Line,
699 ExchangeTimeBoarding,
700 ExchangeTimeDisembarking,
701 TransportType,
702}
703
704#[derive(Debug, Serialize, Deserialize)]
709pub struct JourneyMetadataEntry {
710 from_stop_id: Option<i32>,
711 until_stop_id: Option<i32>,
712 resource_id: Option<i32>,
713 bit_field_id: Option<i32>,
714 departure_time: Option<NaiveTime>,
715 arrival_time: Option<NaiveTime>,
716 extra_field_1: Option<String>,
717 extra_field_2: Option<i32>,
718}
719
720impl JourneyMetadataEntry {
721 #[allow(clippy::too_many_arguments)]
722 pub fn new(
723 from_stop_id: Option<i32>,
724 until_stop_id: Option<i32>,
725 resource_id: Option<i32>,
726 bit_field_id: Option<i32>,
727 departure_time: Option<NaiveTime>,
728 arrival_time: Option<NaiveTime>,
729 extra_field_1: Option<String>,
730 extra_field_2: Option<i32>,
731 ) -> Self {
732 Self {
733 from_stop_id,
734 until_stop_id,
735 resource_id,
736 bit_field_id,
737 departure_time,
738 arrival_time,
739 extra_field_1,
740 extra_field_2,
741 }
742 }
743}
744
745#[derive(Debug, Serialize, Deserialize)]
750pub struct JourneyRouteEntry {
751 stop_id: i32,
752 arrival_time: Option<NaiveTime>,
753 departure_time: Option<NaiveTime>,
754}
755
756impl JourneyRouteEntry {
757 pub fn new(
758 stop_id: i32,
759 arrival_time: Option<NaiveTime>,
760 departure_time: Option<NaiveTime>,
761 ) -> Self {
762 Self {
763 stop_id,
764 arrival_time,
765 departure_time,
766 }
767 }
768
769 pub fn stop_id(&self) -> i32 {
772 self.stop_id
773 }
774
775 pub fn arrival_time(&self) -> &Option<NaiveTime> {
776 &self.arrival_time
777 }
778
779 pub fn departure_time(&self) -> &Option<NaiveTime> {
780 &self.departure_time
781 }
782
783 pub fn stop<'a>(&'a self, data_storage: &'a DataStorage) -> &Stop {
786 data_storage
787 .stops()
788 .find(self.stop_id())
789 .unwrap_or_else(|| panic!("Stop {:?} not found.", self.stop_id()))
790 }
791}
792
793#[derive(Debug, Serialize, Deserialize)]
798pub struct JourneyPlatform {
799 journey_id: i32,
800 platform_id: i32,
801 time: Option<NaiveTime>,
802 bit_field_id: Option<i32>,
803}
804
805impl JourneyPlatform {
806 pub fn new(
807 journey_id: i32,
808 platform_id: i32,
809 time: Option<NaiveTime>,
810 bit_field_id: Option<i32>,
811 ) -> Self {
812 Self {
813 journey_id,
814 platform_id,
815 time,
816 bit_field_id,
817 }
818 }
819}
820
821impl Model<JourneyPlatform> for JourneyPlatform {
822 type K = (i32, i32);
823
824 fn id(&self) -> Self::K {
825 (self.journey_id, self.platform_id)
826 }
827}
828
829#[derive(
834 Clone, Copy, Debug, Default, Display, Eq, Hash, PartialEq, EnumString, Serialize, Deserialize,
835)]
836pub enum Language {
837 #[default]
838 #[strum(serialize = "deu")]
839 German,
840
841 #[strum(serialize = "fra")]
842 French,
843
844 #[strum(serialize = "ita")]
845 Italian,
846
847 #[strum(serialize = "eng")]
848 English,
849}
850
851#[derive(Debug, Default, Serialize, Deserialize)]
856pub struct Line {
857 id: i32,
858 name: String,
859 short_name: String,
860 text_color: Color,
861 background_color: Color,
862}
863
864impl_Model!(Line);
865
866impl Line {
867 pub fn new(id: i32, name: String) -> Self {
868 Self {
869 id,
870 name,
871 short_name: String::default(),
872 text_color: Color::default(),
873 background_color: Color::default(),
874 }
875 }
876
877 pub fn set_short_name(&mut self, value: String) {
880 self.short_name = value;
881 }
882
883 pub fn set_text_color(&mut self, value: Color) {
884 self.text_color = value;
885 }
886
887 pub fn set_background_color(&mut self, value: Color) {
888 self.background_color = value;
889 }
890}
891
892#[derive(Debug, Serialize, Deserialize)]
897pub struct Platform {
898 id: i32,
899 name: String,
900 sectors: Option<String>,
901 stop_id: i32,
902 sloid: String,
903 lv95_coordinates: Coordinates,
904 wgs84_coordinates: Coordinates,
905}
906
907impl_Model!(Platform);
908
909impl Platform {
910 pub fn new(id: i32, name: String, sectors: Option<String>, stop_id: i32) -> Self {
911 Self {
912 id,
913 name,
914 sectors,
915 stop_id,
916 sloid: String::default(),
917 lv95_coordinates: Coordinates::default(),
918 wgs84_coordinates: Coordinates::default(),
919 }
920 }
921
922 pub fn set_sloid(&mut self, value: String) {
925 self.sloid = value;
926 }
927
928 pub fn set_lv95_coordinates(&mut self, value: Coordinates) {
929 self.lv95_coordinates = value;
930 }
931
932 pub fn set_wgs84_coordinates(&mut self, value: Coordinates) {
933 self.wgs84_coordinates = value;
934 }
935}
936
937#[derive(Debug, Serialize, Deserialize)]
942pub struct Stop {
943 id: i32,
944 name: String,
945 long_name: Option<String>,
946 abbreviation: Option<String>,
947 synonyms: Option<Vec<String>>,
948 lv95_coordinates: Option<Coordinates>,
949 wgs84_coordinates: Option<Coordinates>,
950 exchange_priority: i16,
951 exchange_flag: i16,
952 exchange_time: Option<(i16, i16)>, restrictions: i16,
954 sloid: String,
955 boarding_areas: Vec<String>,
956}
957
958impl_Model!(Stop);
959
960impl Stop {
961 pub fn new(
962 id: i32,
963 name: String,
964 long_name: Option<String>,
965 abbreviation: Option<String>,
966 synonyms: Option<Vec<String>>,
967 ) -> Self {
968 Self {
969 id,
970 name,
971 long_name,
972 abbreviation,
973 synonyms,
974 lv95_coordinates: None,
975 wgs84_coordinates: None,
976 exchange_priority: 8, exchange_flag: 0,
978 exchange_time: None,
979 restrictions: 0,
980 sloid: String::default(),
981 boarding_areas: Vec::new(),
982 }
983 }
984
985 pub fn name(&self) -> &str {
988 &self.name
989 }
990
991 pub fn lv95_coordinates(&self) -> Option<Coordinates> {
992 self.lv95_coordinates
993 }
994
995 pub fn set_lv95_coordinates(&mut self, value: Coordinates) {
996 self.lv95_coordinates = Some(value);
997 }
998
999 pub fn wgs84_coordinates(&self) -> Option<Coordinates> {
1000 self.wgs84_coordinates
1001 }
1002
1003 pub fn set_wgs84_coordinates(&mut self, value: Coordinates) {
1004 self.wgs84_coordinates = Some(value);
1005 }
1006
1007 pub fn set_exchange_priority(&mut self, value: i16) {
1008 self.exchange_priority = value;
1009 }
1010
1011 pub fn exchange_flag(&self) -> i16 {
1012 self.exchange_flag
1013 }
1014
1015 pub fn set_exchange_flag(&mut self, value: i16) {
1016 self.exchange_flag = value;
1017 }
1018
1019 pub fn exchange_time(&self) -> Option<(i16, i16)> {
1020 self.exchange_time
1021 }
1022
1023 pub fn set_exchange_time(&mut self, value: Option<(i16, i16)>) {
1024 self.exchange_time = value;
1025 }
1026
1027 pub fn set_restrictions(&mut self, value: i16) {
1028 self.restrictions = value;
1029 }
1030
1031 pub fn set_sloid(&mut self, value: String) {
1032 self.sloid = value;
1033 }
1034
1035 pub fn add_boarding_area(&mut self, value: String) {
1038 self.boarding_areas.push(value);
1039 }
1040
1041 pub fn can_be_used_as_exchange_point(&self) -> bool {
1042 self.exchange_flag() != 0
1043 }
1044}
1045
1046#[derive(Debug, Default, Serialize, Deserialize)]
1051pub struct StopConnection {
1052 id: i32,
1053 stop_id_1: i32,
1054 stop_id_2: i32,
1055 duration: i16, attribute: i32,
1057}
1058
1059impl_Model!(StopConnection);
1060
1061impl StopConnection {
1062 pub fn new(id: i32, stop_id_1: i32, stop_id_2: i32, duration: i16) -> Self {
1063 Self {
1064 id,
1065 stop_id_1,
1066 stop_id_2,
1067 duration,
1068 attribute: 0,
1069 }
1070 }
1071
1072 pub fn stop_id_1(&self) -> i32 {
1075 self.stop_id_1
1076 }
1077
1078 pub fn stop_id_2(&self) -> i32 {
1079 self.stop_id_2
1080 }
1081
1082 pub fn duration(&self) -> i16 {
1083 self.duration
1084 }
1085
1086 pub fn set_attribute(&mut self, value: i32) {
1087 self.attribute = value;
1088 }
1089}
1090
1091#[derive(Debug, Serialize, Deserialize)]
1096pub struct ThroughService {
1097 id: i32,
1098 journey_1_id: i32,
1099 journey_1_stop_id: i32, journey_2_id: i32,
1101 journey_2_stop_id: Option<i32>, bit_field_id: i32,
1103}
1104
1105impl_Model!(ThroughService);
1106
1107impl ThroughService {
1108 pub fn new(
1109 id: i32,
1110 journey_1_id: i32,
1111 journey_1_stop_id: i32,
1112 journey_2_id: i32,
1113 journey_2_stop_id: Option<i32>,
1114 bit_field_id: i32,
1115 ) -> Self {
1116 Self {
1117 id,
1118 journey_1_id,
1119 journey_1_stop_id,
1120 journey_2_id,
1121 journey_2_stop_id,
1122 bit_field_id,
1123 }
1124 }
1125}
1126
1127#[derive(Debug, Serialize, Deserialize)]
1132pub struct TimetableMetadataEntry {
1133 id: i32,
1134 key: String,
1135 value: String,
1136}
1137
1138impl_Model!(TimetableMetadataEntry);
1139
1140impl TimetableMetadataEntry {
1141 pub fn new(id: i32, key: String, value: String) -> Self {
1142 Self { id, key, value }
1143 }
1144
1145 pub fn key(&self) -> &str {
1148 &self.key
1149 }
1150
1151 pub fn value(&self) -> &str {
1152 &self.value
1153 }
1154
1155 #[allow(non_snake_case)]
1157 pub fn value_as_NaiveDate(&self) -> NaiveDate {
1158 NaiveDate::parse_from_str(self.value(), "%Y-%m-%d").unwrap()
1159 }
1160}
1161
1162#[derive(Debug, Serialize, Deserialize)]
1167pub struct TransportCompany {
1168 id: i32,
1169 short_name: FxHashMap<Language, String>,
1170 long_name: FxHashMap<Language, String>,
1171 full_name: FxHashMap<Language, String>,
1172 administrations: Vec<String>,
1173}
1174
1175impl_Model!(TransportCompany);
1176
1177impl TransportCompany {
1178 pub fn new(id: i32, administrations: Vec<String>) -> Self {
1179 Self {
1180 id,
1181 short_name: FxHashMap::default(),
1182 long_name: FxHashMap::default(),
1183 full_name: FxHashMap::default(),
1184 administrations,
1185 }
1186 }
1187
1188 pub fn set_short_name(&mut self, language: Language, value: &str) {
1191 self.short_name.insert(language, value.to_string());
1192 }
1193
1194 pub fn set_long_name(&mut self, language: Language, value: &str) {
1195 self.long_name.insert(language, value.to_string());
1196 }
1197
1198 pub fn set_full_name(&mut self, language: Language, value: &str) {
1199 self.full_name.insert(language, value.to_string());
1200 }
1201}
1202
1203#[derive(Debug, Default, Serialize, Deserialize)]
1208pub struct TransportType {
1209 id: i32,
1210 designation: String,
1211 product_class_id: i16,
1212 tarrif_group: String,
1213 output_control: i16,
1214 short_name: String,
1215 surchage: i16,
1216 flag: String,
1217 product_class_name: FxHashMap<Language, String>,
1218 category_name: FxHashMap<Language, String>,
1219}
1220
1221impl_Model!(TransportType);
1222
1223impl TransportType {
1224 #[allow(clippy::too_many_arguments)]
1225 pub fn new(
1226 id: i32,
1227 designation: String,
1228 product_class_id: i16,
1229 tarrif_group: String,
1230 output_control: i16,
1231 short_name: String,
1232 surchage: i16,
1233 flag: String,
1234 ) -> Self {
1235 Self {
1236 id,
1237 designation,
1238 product_class_id,
1239 tarrif_group,
1240 output_control,
1241 short_name,
1242 surchage,
1243 flag,
1244 product_class_name: FxHashMap::default(),
1245 category_name: FxHashMap::default(),
1246 }
1247 }
1248
1249 pub fn designation(&self) -> &str {
1252 &self.designation
1253 }
1254
1255 pub fn product_class_id(&self) -> i16 {
1256 self.product_class_id
1257 }
1258
1259 pub fn set_product_class_name(&mut self, language: Language, value: &str) {
1260 self.product_class_name.insert(language, value.to_string());
1261 }
1262
1263 pub fn set_category_name(&mut self, language: Language, value: &str) {
1264 self.category_name.insert(language, value.to_string());
1265 }
1266}
1267
1268#[derive(Clone, Copy, Debug, Display, Eq, Hash, PartialEq, Serialize, Deserialize)]
1273#[allow(non_camel_case_types)]
1274pub enum Version {
1275 V_5_40_41_2_0_4,
1276 V_5_40_41_2_0_5,
1277}