gistools/readers/gtfs/realtime/
alert.rs

1use crate::{
2    readers::{GTFSRealtimeEntitySelector, GTFSRealtimeTranslatedString},
3    util::Date,
4};
5use alloc::vec::Vec;
6use pbf::{BitCast, ProtoRead, Protobuf};
7
8/// Severity of this alert.
9#[repr(u8)]
10#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, BitCast)]
11pub enum GTFSRealtimeSeverityLevel {
12    /// Unknown severity level
13    #[default]
14    UnknownSeverity = 1,
15    /// Informational message
16    Info = 2,
17    /// Warning
18    Warning = 3,
19    /// Severe problem
20    Severe = 4,
21}
22
23/// What is the effect of this problem on the affected entity. If effect_detail is included, then
24/// Effect must also be included.
25#[repr(u8)]
26#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, BitCast)]
27pub enum GTFSRealtimeEffect {
28    /// No service
29    NoService = 1,
30    /// Reduced service
31    ReducedService = 2,
32    /// We don't care about INsignificant delays: they are hard to detect, have
33    /// little impact on the user, and would clutter the results as they are too
34    /// frequent.
35    SignificantDelays = 3,
36    /// Detour
37    Detour = 4,
38    /// Additional service
39    AdditionalService = 5,
40    /// Modified service
41    ModifiedService = 6,
42    /// Other effect
43    OtherEffect = 7,
44    /// Unknown effect
45    #[default]
46    UnknownEffect = 8,
47    /// Stop moved
48    StopMoved = 9,
49    /// No effect
50    NoEffect = 10,
51    /// Accessibility issue
52    AccessibilityIssue = 11,
53}
54
55/// Cause of this alert. If cause_detail is included, then Cause must also be included.
56#[repr(u8)]
57#[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, BitCast)]
58pub enum GTFSRealtimeCause {
59    /// Unknown cause
60    #[default]
61    UnknownCause = 1,
62    /// Not machine-representable.
63    OtherCause = 2,
64    /// Technical problem.
65    TechnicalProblem = 3,
66    /// Public transit agency employees stopped working.
67    Strike = 4,
68    /// People are blocking the streets.
69    Demonstration = 5,
70    /// Accident.
71    Accident = 6,
72    /// Holiday.
73    HOLIHolidayDAY = 7,
74    /// Weather.
75    Weather = 8,
76    /// Maintenance.
77    Maintenance = 9,
78    /// Construction.
79    Construction = 10,
80    /// Police activity.
81    PoliceActivity = 11,
82    /// Medical emergency.
83    MedicalEmergency = 12,
84}
85
86/// An alert, indicating some sort of incident in the public transit network.
87#[derive(Debug, Default, Clone, PartialEq)]
88pub struct GTFSRealtimeAlert {
89    /// Time when the alert should be shown to the user. If missing, the
90    /// alert will be shown as long as it appears in the feed.
91    /// If multiple ranges are given, the alert will be shown during all of them.
92    pub active_periods: Vec<GTFSRealtimeTimeRange>, // 1 [repeated message]
93    /// Entities whose users we should notify of this alert.
94    pub informed_entities: Vec<GTFSRealtimeEntitySelector>, // 5 [repeated message]
95    /// Cause of this alert. If cause_detail is included, then Cause must also be included.
96    pub cause: GTFSRealtimeCause, // 6 [enum]
97    /// What is the effect of this problem on the affected entity. If effect_detail is included, then
98    /// Effect must also be included.
99    pub effect: GTFSRealtimeEffect, // 7 [enum]
100    /// The URL which provides additional information about the alert.
101    pub url: Option<GTFSRealtimeTranslatedString>, // 8 [message]
102    /// Alert header. Contains a short summary of the alert text as plain-text.
103    pub header_text: Option<GTFSRealtimeTranslatedString>, // 10 [message]
104    /// Full description for the alert as plain-text. The information in the
105    /// description should add to the information of the header.
106    pub description_text: Option<GTFSRealtimeTranslatedString>, // 11 [message]
107    /// Text for alert header to be used in text-to-speech implementations. This field is the
108    /// text-to-speech version of header_text.
109    pub tts_header_text: Option<GTFSRealtimeTranslatedString>, // 12 [message]
110    /// Text for full description for the alert to be used in text-to-speech implementations.
111    /// This field is the text-to-speech version of description_text.
112    pub tts_description_text: Option<GTFSRealtimeTranslatedString>, // 13 [message]
113    /// Severity of this alert.
114    pub severity_level: GTFSRealtimeSeverityLevel, // 14 [enum]
115    /// TranslatedImage to be displayed along the alert text. Used to explain visually the alert effect of a detour, station closure, etc. The image must enhance the understanding of the alert. Any essential information communicated within the image must also be contained in the alert text.
116    /// The following types of images are discouraged : image containing mainly text, marketing or branded images that add no additional information.
117    /// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
118    pub image: Option<GTFSRealtimeTranslatedString>, // 15 [message]
119    /// Text describing the appearance of the linked image in the `image` field (e.g., in case the image can't be displayed
120    /// or the user can't see the image for accessibility reasons). See the HTML spec for alt image text - <https://html.spec.whatwg.org/#alt>.
121    /// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future
122    pub image_alternative_text: Option<GTFSRealtimeTranslatedString>, // 16 [message]
123    /// Description of the cause of the alert that allows for agency-specific language, more specific than the Cause. If cause_detail is included, then Cause must also be included.
124    /// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
125    pub cause_detail: Option<GTFSRealtimeTranslatedString>, // 17 [message]
126    /// Description of the effect of the alert that allows for agency-specific language, more specific than the Effect. If effect_detail is included, then Effect must also be included.
127    /// NOTE: This field is still experimental, and subject to change. It may be formally adopted in the future.
128    pub effect_detail: Option<GTFSRealtimeTranslatedString>, // 18 [message]
129}
130/// Read in the contents of the GTFSRealtimeAlert
131impl ProtoRead for GTFSRealtimeAlert {
132    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
133        match tag {
134            1 => {
135                let mut time_range = GTFSRealtimeTimeRange::default();
136                pb.read_message(&mut time_range);
137                self.active_periods.push(time_range);
138            }
139            5 => {
140                let mut entity_selector = GTFSRealtimeEntitySelector::default();
141                pb.read_message(&mut entity_selector);
142                self.informed_entities.push(entity_selector);
143            }
144            6 => self.cause = pb.read_varint(),
145            7 => self.effect = pb.read_varint(),
146            8 => {
147                let mut translated_string = GTFSRealtimeTranslatedString::default();
148                pb.read_message(&mut translated_string);
149                self.url = Some(translated_string);
150            }
151            10 => {
152                let mut translated_string = GTFSRealtimeTranslatedString::default();
153                pb.read_message(&mut translated_string);
154                self.header_text = Some(translated_string);
155            }
156            11 => {
157                let mut translated_string = GTFSRealtimeTranslatedString::default();
158                pb.read_message(&mut translated_string);
159                self.description_text = Some(translated_string);
160            }
161            12 => {
162                let mut translated_string = GTFSRealtimeTranslatedString::default();
163                pb.read_message(&mut translated_string);
164                self.tts_header_text = Some(translated_string);
165            }
166            13 => {
167                let mut translated_string = GTFSRealtimeTranslatedString::default();
168                pb.read_message(&mut translated_string);
169                self.tts_description_text = Some(translated_string);
170            }
171            14 => self.severity_level = pb.read_varint(),
172            // NOTE: These are still experimental fields not yet added. Keeping them here for future
173            // use.
174            // 15 => {
175            //     let mut translated_string = GTFSRealtimeTranslatedString::default();
176            //     pb.read_message(&mut translated_string);
177            //     self.image = Some(translated_string);
178            // }
179            // 16 => {
180            //     let mut translated_string = GTFSRealtimeTranslatedString::default();
181            //     pb.read_message(&mut translated_string);
182            //     self.image_alternative_text = Some(translated_string);
183            // }
184            // 17 => {
185            //     let mut translated_string = GTFSRealtimeTranslatedString::default();
186            //     pb.read_message(&mut translated_string);
187            //     self.cause_detail = Some(translated_string);
188            // }
189            // 18 => {
190            //     let mut translated_string = GTFSRealtimeTranslatedString::default();
191            //     pb.read_message(&mut translated_string);
192            //     self.effect_detail = Some(translated_string);
193            // }
194            _ => panic!("unknown tag {}", tag),
195        }
196    }
197}
198
199/// A time interval. The interval is considered active at time 't' if 't' is
200/// greater than or equal to the start time and less than the end time.
201#[derive(Debug, Default, Clone, PartialEq)]
202pub struct GTFSRealtimeTimeRange {
203    /// Start time, in POSIX time (i.e., number of seconds since January 1st 1970
204    /// 00:00:00 UTC).
205    /// If missing, the interval starts at minus infinity.
206    pub start: Option<Date>, // 1 [uint64]
207    /// End time, in POSIX time (i.e., number of seconds since January 1st 1970
208    /// 00:00:00 UTC).
209    /// If missing, the interval ends at plus infinity.
210    pub end: Option<Date>, // 2 [uint64]
211}
212/// Read in the contents of the GTFSRealtimeTimeRange
213impl ProtoRead for GTFSRealtimeTimeRange {
214    fn read(&mut self, tag: u64, pb: &mut Protobuf) {
215        match tag {
216            1 => self.start = Some(Date::from_time(pb.read_varint::<u64>() as i64 * 1000)),
217            2 => self.end = Some(Date::from_time(pb.read_varint::<u64>() as i64 * 1000)),
218            _ => panic!("unknown tag {}", tag),
219        }
220    }
221}