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}